473,396 Members | 1,834 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Problem with virtual member function pointer (how to invoke the base?!)

Hi everyone,

I have the following code (greatly simplified to demonstrate issue) :

#include <iostream>

class CBaseFuBar {
public:
virtual void Fu() { std::cout << "base"; };
};

class CDerivedFuBar : public CBaseFuBar {
public :
virtual void Fu() { std::cout << "derived"; };
};

typedef void (CBaseFuBar::*FuFxnPtr)();

int main() {
CDerivedFuBar fubar;
FuFxnPtr fxn;
fxn = &CBaseFuBar::Fu;
(fubar.*fxn)(); // prints out "derived" not "base" like I want
std::cin.get();
return 0;
};

The problem is that given CDerivedFuBar I want to get a member function
pointer to refer to the base Fu function and not automatically get resolved
to the derived Fu function. The CBaseFuBar class can not be modified, but
the CDerivedFuBar class can be. Thanks in advance!

--
Christopher Diggins
yet another language designer
http://www.heron-language.com
Jul 22 '05 #1
7 1507
"christopher diggins" <cd******@users.sourceforge.net> wrote...
I have the following code (greatly simplified to demonstrate issue) :

#include <iostream>

class CBaseFuBar {
public:
virtual void Fu() { std::cout << "base"; };
'virtual' is key here.
};

class CDerivedFuBar : public CBaseFuBar {
public :
virtual void Fu() { std::cout << "derived"; };
};

typedef void (CBaseFuBar::*FuFxnPtr)();

int main() {
CDerivedFuBar fubar;
FuFxnPtr fxn;
fxn = &CBaseFuBar::Fu;
(fubar.*fxn)(); // prints out "derived" not "base" like I want
The function is called polymorphically. For all intents and purposes
it works as if you called

fubar.Fu()
std::cin.get();
return 0;
}; ^
This semicolon is a syntax error.

The problem is that given CDerivedFuBar I want to get a member function
pointer to refer to the base Fu function and not automatically get resolved to the derived Fu function. The CBaseFuBar class can not be modified, but
the CDerivedFuBar class can be. Thanks in advance!


Don't use a pointer to member, use direct call

fubar.CBaseFuBar::Fu();

Victor
Jul 22 '05 #2


"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:DTYWb.293273$I06.3017457@attbi_s01...
"christopher diggins" <cd******@users.sourceforge.net> wrote...
I have the following code (greatly simplified to demonstrate issue) :

#include <iostream>

class CBaseFuBar {
public:
virtual void Fu() { std::cout << "base"; };


'virtual' is key here.
};

class CDerivedFuBar : public CBaseFuBar {
public :
virtual void Fu() { std::cout << "derived"; };
};

typedef void (CBaseFuBar::*FuFxnPtr)();

int main() {
CDerivedFuBar fubar;
FuFxnPtr fxn;
fxn = &CBaseFuBar::Fu;
(fubar.*fxn)(); // prints out "derived" not "base" like I want


The function is called polymorphically. For all intents and purposes
it works as if you called

fubar.Fu()


Yes I realize that.
std::cin.get();
return 0;
};

^
This semicolon is a syntax error.


Thank you for pointing that out.

The problem is that given CDerivedFuBar I want to get a member function
pointer to refer to the base Fu function and not automatically get

resolved
to the derived Fu function. The CBaseFuBar class can not be modified, but the CDerivedFuBar class can be. Thanks in advance!


Don't use a pointer to member, use direct call

fubar.CBaseFuBar::Fu();

Victor


The code I am working with specifically requires a function pointer. Is
there a way to accomplish this with a function pointer invoked on a
CDerivedFuBar object?

Thanks for you input.

--
Christopher Diggins
yet another language designer
http://www.heron-language.com
Jul 22 '05 #3

"christopher diggins" <cd******@users.sourceforge.net> schrieb im
Newsbeitrag news:E8********************@weber.videotron.net...
Hi everyone,

I have the following code (greatly simplified to demonstrate issue) :

#include <iostream>

class CBaseFuBar {
public:
virtual void Fu() { std::cout << "base"; };
};

class CDerivedFuBar : public CBaseFuBar {
public :
virtual void Fu() { std::cout << "derived"; };
};

typedef void (CBaseFuBar::*FuFxnPtr)();

int main() {
CDerivedFuBar fubar;
FuFxnPtr fxn;
fxn = &CBaseFuBar::Fu;

at this point your expression will be solved by compiler and the compiler
will always use the address of function CBaseFuBar::Fu.
The only possible way I see is to wrap your virtual funktion in a non
virtual baseclass function. Something like this:
class CBaseFuBar {
public:
virtual void Fu() { std::cout << "base"; };
void WrapIt(){Fu();}
};
now you can use your wrapper function:
int main() {
CDerivedFuBar fubar;
FuFxnPtr fxn;
fxn = &CBaseFuBar::WrapIt();
(fubar.*fxn)(); // should work
std::cin.get();
return 0;
}

regards
Bernhard
Jul 22 '05 #4
"Sommer Bernhard (SMS SW SEC 88T external)" <Mo***********@infineon.com>
wrote...
[...]
The only possible way I see is to wrap your virtual funktion in a non
virtual baseclass function. Something like this:
class CBaseFuBar {
public:
virtual void Fu() { std::cout << "base"; };
void WrapIt(){Fu();}
};


The OP specifically said that the base class could NOT be modified.

Beyond that, your solution should work.
Jul 22 '05 #5
"christopher diggins" <cd******@users.sourceforge.net> wrote...


"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:DTYWb.293273$I06.3017457@attbi_s01...
"christopher diggins" <cd******@users.sourceforge.net> wrote...
I have the following code (greatly simplified to demonstrate issue) :

#include <iostream>

class CBaseFuBar {
public:
virtual void Fu() { std::cout << "base"; };


'virtual' is key here.
};

class CDerivedFuBar : public CBaseFuBar {
public :
virtual void Fu() { std::cout << "derived"; };
};

typedef void (CBaseFuBar::*FuFxnPtr)();

int main() {
CDerivedFuBar fubar;
FuFxnPtr fxn;
fxn = &CBaseFuBar::Fu;
(fubar.*fxn)(); // prints out "derived" not "base" like I want


The function is called polymorphically. For all intents and purposes
it works as if you called

fubar.Fu()


Yes I realize that.
std::cin.get();
return 0;
};

^
This semicolon is a syntax error.


Thank you for pointing that out.

The problem is that given CDerivedFuBar I want to get a member function pointer to refer to the base Fu function and not automatically get

resolved
to the derived Fu function. The CBaseFuBar class can not be modified, but the CDerivedFuBar class can be. Thanks in advance!


Don't use a pointer to member, use direct call

fubar.CBaseFuBar::Fu();

Victor


The code I am working with specifically requires a function pointer. Is
there a way to accomplish this with a function pointer invoked on a
CDerivedFuBar object?


The only thing I can think of is to drop the 'Fu' member from the derived
class. Then, for any instance, the final overrider will be <base>::Fu,
and it will be called through the pointer.

Victor
Jul 22 '05 #6

"Sommer Bernhard (SMS SW SEC 88T external)" <Mo***********@infineon.com> wrote
in message news:c0**********@newssrv.muc.infineon.com...

"christopher diggins" <cd******@users.sourceforge.net> schrieb im
Newsbeitrag news:E8********************@weber.videotron.net...
Hi everyone,

I have the following code (greatly simplified to demonstrate issue) :

#include <iostream>

class CBaseFuBar {
public:
virtual void Fu() { std::cout << "base"; };
};

class CDerivedFuBar : public CBaseFuBar {
public :
virtual void Fu() { std::cout << "derived"; };
};

typedef void (CBaseFuBar::*FuFxnPtr)();

int main() {
CDerivedFuBar fubar;
FuFxnPtr fxn;
fxn = &CBaseFuBar::Fu;

at this point your expression will be solved by compiler and the compiler
will always use the address of function CBaseFuBar::Fu.
The only possible way I see is to wrap your virtual funktion in a non
virtual baseclass function. Something like this:
class CBaseFuBar {
public:
virtual void Fu() { std::cout << "base"; };
void WrapIt(){Fu();}
};
now you can use your wrapper function:
int main() {
CDerivedFuBar fubar;
FuFxnPtr fxn;
fxn = &CBaseFuBar::WrapIt();

This will fail to compile. It should be fxn = &CBaseFuBar::WrapIt; // NO braces
Also this program will also print derived and not base.

-Sharad
Jul 22 '05 #7
"Sommer Bernhard (SMS SW SEC 88T external)" <Mo***********@infineon.com>
wrote in message news:c0**********@newssrv.muc.infineon.com...

"christopher diggins" <cd******@users.sourceforge.net> schrieb im
Newsbeitrag news:E8********************@weber.videotron.net...
Hi everyone,

I have the following code (greatly simplified to demonstrate issue) :

#include <iostream>

class CBaseFuBar {
public:
virtual void Fu() { std::cout << "base"; };
};

class CDerivedFuBar : public CBaseFuBar {
public :
virtual void Fu() { std::cout << "derived"; };
};

typedef void (CBaseFuBar::*FuFxnPtr)();

int main() {
CDerivedFuBar fubar;
FuFxnPtr fxn;
fxn = &CBaseFuBar::Fu;

at this point your expression will be solved by compiler and the compiler
will always use the address of function CBaseFuBar::Fu.
The only possible way I see is to wrap your virtual funktion in a non
virtual baseclass function. Something like this:
class CBaseFuBar {
public:
virtual void Fu() { std::cout << "base"; };
void WrapIt(){Fu();}
};
now you can use your wrapper function:
int main() {
CDerivedFuBar fubar;
FuFxnPtr fxn;
fxn = &CBaseFuBar::WrapIt();
(fubar.*fxn)(); // should work
std::cin.get();
return 0;
}

regards
Bernhard


Thanks for the input. I mentioned in the original post that CBaseFuBar could
not be modified, though that can be remedied easily if we place the wrapper
in the derived class :

class CDerivedFuBar {
virtual void Fu() { std::cout << "derived"; };
void WrapFu() { CBaseFuBar::Fu(); };
};
etc.

This is a working solution but not a very practical one unfortunately. I
would have to write a new wrapper function in every derived class for every
virtual function. That would be a heck of a nasty requirement to put on
users who derive from CBaseFuBar. You can imagine the redundancy as my
project scales up. I believe though that this is in fact the best we can do
with the limitations of the current standard. I am just hoping someone
proves us wrong. `

--
Christopher Diggins
yet another language designer
http://www.heron-language.com
Jul 22 '05 #8

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

Similar topics

4
by: DaKoadMunky | last post by:
I was recently looking at some assembly code generated by my compiler. When examining the assembly code associated with constructors I noticed that the dynamic-dispatch mechanism was enabled...
4
by: Merlin | last post by:
Hi Imagine the following classes (A class diagram will help) BASE, A, B, C, D, E, F, G. A, B, C, D, G inherit from BASE. E, F inherit from D.
3
by: Daniel Graifer | last post by:
Why doesn't c++ support virtual data? It supports class data of type pointer to function (that's what virtual functions really are). In terms of implementation, why can't I have other types of...
4
by: WittyGuy | last post by:
Hi all, Though I know the concepts of both abstract class & virtual function (like derived class pointer pointing to base class...then calling the function with the pointer...), what is the real...
10
by: Martin Vorbrodt | last post by:
Example code in one of my books intrigues me: class B { public: B* Clone() const { B* p = DoClone(); assert(typeid(*p) == typeid(*this)); return p; }
175
by: Ken Brady | last post by:
I'm on a team building some class libraries to be used by many other projects. Some members of our team insist that "All public methods should be virtual" just in case "anything needs to be...
3
by: Samuel Burri | last post by:
Hi there I got a simple problem. As you can see in the posted source, I have two classes, where one is derived from the other. In fact, they also contain virtual functions. In the function...
6
by: Gerhard Prilmeier | last post by:
Hello, I have an unmanaged C++ API that uses virtual functions, like this: class A { public: virtual void handleMe(){} };
17
by: Jess | last post by:
Hello, If I have a class that has virtual but non-pure declarations, like class A{ virtual void f(); }; Then is A still an abstract class? Do I have to have "virtual void f() = 0;"...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
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...
0
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...
0
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...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

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.