Attempts to compile such code had the compiler complaining a lot and my attempts to make it work have lead me down other roads but none have lead to what I want.
I know I can do something similar with code such as this :
I had that initially, but I found it was a problem because derived classes can't override the behaviour of 'init()' when it is called from the constructor.
Of course, I can do this explicitly in the calling code :
1 2 3 4 5 6 7 8
int main()
{
...
MyClass myClass;
myClass.init();
myClass.publicFunc();
...
}
but it seems to me that this then gives an opportunity for the author of the calling code to introduce an error by not initialising the class. Thus, I want to put the 'init()' call in the 'publicFunc()', but only have it called the first time - this objective is attained by having the 'if' statement with a static, but I thought the 'if' could be avoided by using a function pointer which could be changed the first time it is called.
Found it. I used the code on this page to help me <http://www.goingware.com/tips/member-pointers.html> - it seems I need to go through this extra method I've called 'myPublic2()'. This is what I ended up with :
However, on the same page I reference above, it suggests that it is pointless to do this, at least for my case, and a if-static is likely much more efficient. At least I now know :)
Because I want to override the 'Base::init()' class by making it virtual and defining another one in the derived class; and if you call it from the Base's constructor, then it'll still call the one in the base class, and not the one in the derived class.
Oh, I get it now... You don't want the base init to be called at all... Mmmm... There must be some other way... I'll think of it for a while and tell you if I come up with something.
Yeah. While describing it to someone here, they said I was using the base class as an interface with the default implementation, but when I derive another class from it, I am making a different implementation.
The second implementation is one I want to use for a unit test - ie make the implementation of my interface just pretend things are happening in the outside world, when really nothing is happening :)
Well, that's where this question is coming from anyway. I was finding that putting anything significant in the constructor was meaning I couldn't change the behaviour, so I was tending to make the constructor just construct a 'null' class and have a separate 'init()' class that would build it into something 'useful'. I think this whole question became somewhat academic/theoretical at some point, and certainly has diverged from something I can actually use in the situation I was thinking of.
Anyway, I think the question was answered, wasn't it? ie,
1) I need to use some intermediate method that de-references the method pointer, or perhaps I can do the same thing outside the class, but it isn't as 'neat' as it is in C, but anyway...
2) there's little point since, as pointed out on that web page, an if-statement based on a 'bool notInitialised' flag is faster anyway - apparently, C++ makes method pointers much more complicated than simple function pointers, and so the advantage is lost (in some cases).
#include <iostream>
usingnamespace std;
class Base
{
private:
void init(){cout << "Initializing Base object..." << endl;}
public:
Base()
{
cout << "Hi, I'm the Base constructor!" << endl;
cout << "I'm taking care of initialization of Base objects," << endl;
cout << "but I must not be called for Derived ones." << endl;
cout << "I'm calling Base::init() now..." << endl;
init();
}
Base(void*) //dummy base constructor
{
cout << "Hi, I'm the dummy Base constructor!" << endl;
cout << "I do absolutely nothing," << endl;
cout << "so it's safe to call me from a Derived object!" << endl;
}
};
class Derived:public Base
{
private:
void init(){cout << "Initializing Derived object..." << endl;}
public:
Derived():Base(0) //call the dummy constructor instead of the default ;)
{
cout << "Hi, I'm the Derived constructor!" << endl;
cout << "I'm taking care of initialization of Derived objects." << endl;
cout << "I'm calling Derived::init() now..." << endl;
init();
}
};
int main()
{
cout << "Declaring a Base object...\n" << endl;
Base base;
cout << "\nDeclaring a Derived object...\n" << endl;
Derived derived;
cout << "\nhit enter to quit..." << endl;
cin.get();
return 0;
}