473,847 Members | 2,011 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

question about method pointers and subclasses

Hello,

Is it legal (and moral) to assign a method pointer with the proper
prototype to a variable whose type involves the superclass? (Sorry if my
wording of the question is imprecise, I'm not sure what all the right
terminology is.) A code example should make it clear what I'm asking:

class A
{
public:
int Fn1( int x );
// ...
};

typedef int (A::*AMemFn)( int x );

class B : public A
{
public:
int Fn2( int x );
// ...
};

// Assume the methods are defined and the classes are completed elsewhere

AMemFn f = &B::Fn2; // Is this OK?

// Two examples of how I am using f:
B b_obj;
int r = (b_obj.*f)( 5 );

A *a_ptr = new B;
r = (a->(*f))( 5 );
In my code, I know that the type of the object and the class that the
method being stored in the variable agree. It still feels sketchy to me
because it seems like you could screw yourself by making an object of
type A and then calling a method of class B on it, which can cause bad
things to happen.

Visual C++ and g++ permit me to do this, but I wanted to know if this
generally should work.
--
yp*@cs.stanford .edu
Jul 19 '05 #1
4 3830
Yu Hu wrote:
Is it legal (and moral) to assign a method pointer with the proper
prototype to a variable whose type involves the superclass? (Sorry if my
wording of the question is imprecise, I'm not sure what all the right
terminology is.) A code example should make it clear what I'm asking:

class A
{
public:
int Fn1( int x );
// ...
};

typedef int (A::*AMemFn)( int x );

class B : public A
{
public:
int Fn2( int x );
// ...
};

// Assume the methods are defined and the classes are completed elsewhere

AMemFn f = &B::Fn2; // Is this OK?
This will not compile. Member pointer types are contravariant, not
covariant. The following, however, is perfectly legal

AMemFn f = static_cast<AMe mFn>(&B::Fn2);

There are obvious dangers in such conversions, so it is up to you to
decide whether it is OK or not OK to do it in your code.
// Two examples of how I am using f:
B b_obj;
int r = (b_obj.*f)( 5 );

A *a_ptr = new B;
r = (a->(*f))( 5 );
In the second case you probably meant

r = (a_ptr->*f)(5);

Both calls are fine, provided the 'f' pointer is initialized as shown above.
In my code, I know that the type of the object and the class that the
method being stored in the variable agree. It still feels sketchy to me
because it seems like you could screw yourself by making an object of
type A and then calling a method of class B on it, which can cause bad
things to happen.
Yes, that's the danger I was talking about.
Visual C++ and g++ permit me to do this, but I wanted to know if this
generally should work.


Yes, it is guaranteed to work by C++ standard.

--
Best regards,
Andrey Tarasevich
Brainbench C and C++ Programming MVP

Jul 19 '05 #2
Yu Hu wrote:
Visual C++ and g++ permit me to do this, but I wanted to know if this
generally should work.


Funny - after I remove some compiler errors, gcc says:

aaa.cpp:19: error: cannot convert `int (B::*)(int)' to `int (A::*)(int)' in

I suspect that you're out of luck. What you tried to do is illegal.

If you KNOW the object is a b then try this instead.

class A
{
public:
int Fn1( int x );
// ...
};
class B : public A
{
public:
int Fn2( int x ) { return 0; }
// ...
};

// Assume the methods are defined and the classes are completed elsewhere

typedef int (B::*BMemFn)( int x );
BMemFn f = &B::Fn2; // Is this OK?

// Two examples of how I am using f:
B b_obj;
int main()
{

int r = (b_obj.*f)( 5 );

A *a_ptr = new B;
r = ( ( static_cast<B*> ( a_ptr ) )->*f)( 5 );
}

Having said that, I suspect you're doing somthing that you could
probably do with virtual methods. Why not use use vritual methods ?

G

Jul 19 '05 #3
In article <bj********@dis patch.concentri c.net>,
Gianni Mariani <gi*******@mari ani.ws> wrote:
Yu Hu wrote:
Visual C++ and g++ permit me to do this, but I wanted to know if this
generally should work.
Funny - after I remove some compiler errors, gcc says:

aaa.cpp:19: error: cannot convert `int (B::*)(int)' to `int (A::*)(int)' in

I suspect that you're out of luck. What you tried to do is illegal.


Oops. I typed the code from memory and forgot that it required an
explicit cast before it would compile, as the other response to my
original post pointed out. My mistake; in the future I'll run it through
a compiler before posting. :)
Having said that, I suspect you're doing somthing that you could
probably do with virtual methods. Why not use use vritual methods ?


This was the first C++ code added to the system, and the way we were
serializing our data would not have worked with objects with vtable
pointers.

I am implementing finite state machines. I wish to avoid using separate
classes for each state, although I've seen that pattern used in a lot of
places. There are many machines being processed simultaneously, with
many different types, so the system wants to call them only through the
common Machine superclass interface.

Machine::Proces sInput needs to switch on the FSM's current state to call
the correct method to handle the input. I can only think of two ways
to do this. One is for ProcessInput to be virtual, and for each subclass
to override this method and use a switch statement there to call the
correct processing method for each state. The other is to store an array
of method pointers, and to index into it (assuming your state is an
offset into the array) to get the right method. Because I couldn't use
virtual methods (see above), I had to use the second option. Does anyone
know of a better way?

If I am allowed to use virtuals, I am definitely considering it. We're
moving our entire code base from C to C++ and other programmers want to
use virtual methods, so someone is going to have to solve the problems
with serialization and such. If so, the only remaining question is
whether writing a table of method pointers is less cumbersome than
writing a switch table to select the correct method.

Thanks for the response; thinking about using virtuals here has helped
shed some light on the problem.
--
yp*@cs.stanford .edu
Jul 19 '05 #4
In article <vl************ @news.supernews .com>,
Andrey Tarasevich <an************ **@hotmail.com> wrote:
AMemFn f = &B::Fn2; // Is this OK?
This will not compile. Member pointer types are contravariant, not
covariant. The following, however, is perfectly legal

AMemFn f = static_cast<AMe mFn>(&B::Fn2);


Oops. My mistake, I forgot the cast was necessary.
There are obvious dangers in such conversions, so it is up to you to
decide whether it is OK or not OK to do it in your code.
Yes, that's the main reason I am not entirely happy with it. So I guess
the question is whether I prefer to use the method pointers, or if I
prefer having virtual methods which switch on the state to select the
correct method to call (see my other post in this thread). The latter is
probably safer.
// Two examples of how I am using f:
B b_obj;
int r = (b_obj.*f)( 5 );

A *a_ptr = new B;
r = (a->(*f))( 5 );


In the second case you probably meant

r = (a_ptr->*f)(5);


Oops again. Yes, I was just being sloppy.
Yes, it is guaranteed to work by C++ standard.


Thanks for the confirmation of that. I may decide not to use them, but I
still had an academic curiosity about whether or not it was ok.
--
yp*@cs.stanford .edu
Jul 19 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
4547
by: Jon | last post by:
Hello all, I'm certain this question has been asked before; I was unsure what terms to search for within the newsgroup archive to find the proper answer I wanted. Hopefully someone can point me to some relevant postings or websites. In any case, I want to create a geometry class that has some base functionalities. The problem I am particularly interested in is such:
8
2440
by: Shaun C Farrugia | last post by:
I have a multi team solution being built where teams are segmented off into seperate projects. One project is an over all framework containing a Broker class responsible for instantiating different subclasses of type Connector - the class only contains the abstract Connector class and the Broker. A seperate project contains the actual subclasses of the Connector that are database specific. Another team will work exclusivley in that...
10
5149
by: Mark | last post by:
I have an abstract class, and a set of classes that inherit from my abstract class. The fact that it is abstract is likely irrelevant. I have a static factory method in my abstract class that creates subclasses. The constructor in my subclasses must be able to call the constructor in my base class. For the factory method in my abstract class to call the constructor on my subclasses, the constructor in the subclass MUST be public (or...
3
1794
by: cmay | last post by:
In reading some documents from the Patterns and Practices group, I had a question about the example given for the Page Controller pattern. (I have posted the code for the BasePage below) In short, their example shows a "BasePage " class for other pages to inherit from. The subclasses are supposed to implement the PageLoadEvent method (which I guess should really be abstract, but can't because asp.net
13
2107
by: yuvalif | last post by:
Hi All, The company I work for is requiting a C++ developer to my team. I prepared the following "test" and I would like to hear some comments about it: is it too hard/easy, if its too specific, is it really testing ones knowledge in C++, etc. It is as following: (1) Explain the following code, what it does? What will be the output of "main"? (2) Write a copy constructor for class "Values".
4
1423
by: Hardy Wang | last post by:
Hi, I have two classes (ClassA and ClassB), public ClassA { public ClassA() { this.MyButton.Clicked += new System.EventHandler(this.MyButton_Click); } private void MyButton_Click(object sender, System.EventArgs e) {
8
3862
by: Gaetan | last post by:
Is is possible in C# to have the equivalent of an array of function pointers in C? I have a situation where a top level class exposes methods like Add, Delete, ... and a few child classes with the same methods. Depending on a configuration parameter, the child method will be invoked when the top level class is invoked. I would like to avoid having to do something like this: int configuration;
1
1377
by: Hermann Lichte | last post by:
Hi, I've naively written a piece of code that's not doing what I want it to. I want to store objects in a vector of some base class A. This base class provides a method doSomething() that is overridden in subclasses. When I invoke doSomething() I always end up with the implementation provided by the base class A, regardless the subclass I used for instantiating the object. I suppose that this is related to the fact that the vector...
10
1534
by: =?iso-8859-1?B?QW5kcuk=?= | last post by:
In my application, I make use of the Borg idiom, invented by Alex Martelli. class Borg(object): '''Borg Idiom, from the Python Cookbook, 2nd Edition, p:273 Derive a class form this; all instances of that class will share the same state, provided that they don't override __new__; otherwise, remember to use Borg.__new__ within the overriden class.
0
9887
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9730
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10650
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
10342
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
7883
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5912
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4531
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
4122
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
3164
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.