I want to do some processing before the parent constructor is called. The following example shows why I want to do this despite the fact that I have made it slightly trivial for the sake of clarity. The real parent constructor is doing some rendering, but lets try and solve this problem first.
Essentially, the problem comes in when an overriden function is called by the parent constructor, but the child's data is not set up yet. How do I fix this?
class BaseClass {
public:
int myNumber;
BaseClass(){
myNumber = 0;
this->printNumber();
}
virtual void printNumber(){
printf("My number is %d\n", this->myNumber);
}
}
class ChildClass : BaseClass {
public:
float childNumber;
ChildClass(float myNumber) : BaseClass() {
this->childNumber = myNumber;
}
void printNumber(){
printf("My number is %f\n", this->childNumber);
}
}
the problem comes in when an overriden function is called by the parent constructor,
No, that never happens. Within the constructor of BaseClass its dynamic type is BaseClass as well, so the printNumber() call will resolve to its own number instead of some derived class. Why? Because at that time the constructors for ChildClass has not yet finished running and so it wasn't yet created.
As #FredLarson comments, here is more info on the subject: http://parashift.com/c++-faq/calling-virtuals-from-ctors.html
Like others said above, you shouldn't call a virtual member from a constructor. But to address your problem there is an idiom that might help you, it is called base-from-member:
http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Base-from-Member
What it does basically, is take advantage of the fact that base classes are initialized in the order they are declared. You may be able to do what you need to do in a separate base class before your base class is initialized.
class OtherBaseClass {
int Num;
OtherBaseclass(float num) : Num(num)
{
printf("My number is %d\n", this->Num);
}
};
class ChildClass : OtherBaseClass, BaseClass {
public:
float childNumber;
ChildClass(float myNumber) : OtherBaseClass(myNumber), BaseClass() {
....
Note that the constructor of the base class cannot call to the virtual function version of the derived class, that is, your ChildClass::printNumber() function will not be called.
That said, if you want to execute something before the constructor of the base class, one way to do it is using yet another base class, and put it before the other one:
class RunMeFirst
{
public RunMeFirst()
{ printf("whatever...\n"); }
};
class ChildClass : private RunMeFirst, public BaseClass
{ /*...*/ };
Do you have to implement the rendering functionality in a base class? Could you instead employ composition instead of inheritance. Using composition would allow you to easily control the member initialization order, e.g.:
#include <iostream>
class renderer
{
public:
renderer(int number)
{
std::cout << "Number is " << number << std::endl;
}
};
class foo
{
public:
foo()
: number_(12)
, renderer_(number_)
{
}
private:
int number_;
renderer renderer_;
};
int main()
{
foo bar;
}
In general, prefer composition to inheritance. Also, the Liskov Substitution Principle may be of use here, too, from a design point of view.
There are several things that run before a base class' constructor:
Initialization of arguments
Virtual base classes' constructors
Other base classes declared earlier's constructors
One commonly used solution is called the "base from member idiom" and involves moving the member to a new base class that is constructed first.
Thanks to #K-ballo for pointing out the error and because of that I was able to restructure the code a bit to do what I wanted, but as this isnt a technical correct answer to the question either, Ill leave the correct answer as is.
class BaseClass {
public:
int myNumber;
BaseClass(bool initialize = true){
myNumber = 0;
if (initialize){
this->initialize();
}
}
void initialize(){
this->printNumber();
}
virtual void printNumber(){
printf("My number is %d\n", this->myNumber);
}
}
class ChildClass : BaseClass {
public:
float childNumber;
ChildClass(float myNumber) : BaseClass(false) {
this->childNumber = myNumber;
this->initialize();
}
void printNumber(){
printf("My number is %f\n", this->childNumber);
}
}
Related
How to avoid The private function calling indirectly using base class virtual function.
class baseclass{
public:
virtual void printmynumber() = 0;
};
class derivedclass : public baseclass
{
private:
int m_mynumber;
void printmynumber()
{
cout << m_mynumber << endl;
}
public:
derivedclass(int n)
{
m_mynumber = n;
}
};
void main()
{
baseclass *bObj = new derivedclass(10);
bObj->printmynumber();
delete bObj;
}
How to avoid the calling of private function?
You cannot.
void printmynumber() is part of the public API of baseclass, hence of derivedclass. If you wished derivedclass::printmynumber() not to be public, maybe derivedclass shouldn't inherit from baseclass.
As suggested in the comments, this is a violation of the Liskov substitution principle: the L in SOLID.
You can't do that with inheritance. Given a pointer to baseclass, the compiler only knows it has a public virtual function, so allows calling the function accordingly.
The derived class has elected to inherit from the base class, and has implemented a function with different access. But none of that is visible, given only a pointer to the base.
There is nothing preventing derivedclass::printmynumber() from being implemented to do nothing - which means if code calls it, there will be no observable effect (assuming absence of an expected effect is tolerable).
The real solution is to fix your design, not to try to work around deficiencies in it. Don't inherit derivedclass from baseclass. That way, no member function of derivedclass can be called at all, given only a pointer to baseclass, since the types are not related (passing a derivedclass * to a function expecting a baseclass * will normally be diagnosed as an error).
BTW: main() returns int, not void. Some compilers support void main() as a non-standard extension (and the documentation for some of those compilers falsely describes such a thing as standard) but it is better avoided.
The only way I can see to prevent it without modifying the base class, is to add another inheritance-layer between between the original base-class and the final derived class. In that middle class you make the function private or deleted. And then you use a pointer to that middle class as the base pointer.
Something like
class baseclass
{
public:
virtual void printmynumber() = 0;
};
struct middleclass : public baseclass
{
void printmynumber() = delete;
};
class derivedclass : public middleclass
{
private:
int m_mynumber;
void printmynumber()
{
cout << m_mynumber << endl;
}
public:
derivedclass(int n)
{
m_mynumber = n;
}
};
void main()
{
// Here use the middleclass instead of the baseclass
middleclass *bObj = new derivedclass(10);
// printmynumber is deleted in the middleclass and can't be called
// This will result in a build error
bObj->printmynumber();
delete bObj;
}
This of course requires modifications of all places where the original base class is used, but it won't need modifications to the base class itself. So it's a trade-off.
Please look at this code. It just reflects basic concept of what I want to do:
#include <iostream>
using namespace std;
class Base
{
public:
Base()
{
/* Some code I want to reuse */
Redefined();
}
virtual ~Base() {}
void Redefined() { val = 10; }
int val;
};
class Derived : public Base
{
public:
Derived() : Base() {}
~Derived() {}
void Redefined() { val = 25; }
};
int main()
{
Base* check = new Derived();
cout << check->val << endl;
system("pause");
return 0;
}
I want the val property of check object to be 25 instead of 10.
As you can see I have two classes. Base class constructor have some complex functionality, which I want Derived class to have in it's constructor as well. How can I change derived function Redefined so that I won't have to rewrite Derived constructor completely (in fact just copy-pasting the whole base class constructor code and replacing one single line of code - updated version of Redefined function)?
You can't really override a function that way. Normally you could use a virtual functions, but that doesn't work the way you want in the constructor.
A better way is to pass the value you want to the Base constructor:
class Base
{
public:
Base(int init_val = 10)
{
/* Some code I want to reuse */
val = init_val;
}
virtual ~Base() {}
int val;
};
class Derived : public Base
{
public:
Derived() : Base(25) {}
~Derived() {}
};
That way any derived class can pass its choice of value to the base class.
Based on comments above:
I would actually think that the correct solution is to have a "interface" type baseclass (that is, a baseclass with pure virtual functions, and the derived class actually implements the correct behaviour), and then let each class deal with constructing its own DirectX buffers. You may find that you need, say, 2-3 different derived classes that construct buffers in different ways, and then derive from those the classes that actually do the real work. I hope that makes sense.
Alternatively, you would be passing enough parameters to the base-class, such that the buffers can be constructed. But I think the first suggestion is a better choice.
EDIT:
I have no updated the question, whilst doing so I realized the scope of the question has completely changed, so I apologize for this. I am dealing with Threads so that static function has to be there. I have tried to abstract the Threading stuff out of the question as much as possible.
I am getting a pure virtual function call error, so I thought maybe I have the implementation wrong. Here is what I have:
class Base
{
protected:
virtual int f(void) = 0;
static void baseFunction(void* param);
};
static void Base::baseFunction (void* param)
{
Base *parent = (Base*) parameter;
int i = parent->f();
}
class Derived : public Base
{
private:
int _memeber;
int f(void);
};
int Derived::f(void)
{
_member = 0;
cout << "Derived _memeber is: " << _member << endl;
return 0;
}
void main ()
{
Derived d;
d.baseFunction(d);
}
I need the function Derived::f(void) to have access to the Derived class members.
The definition looks fine, but I will hazard a guess that you're calling the virtual function from the constructor or destructor of Base. In that case, virtual dispatch is done as if the dynamic type were Base, not Derived, and if the function is pure virtual then you get undefined behaviour.
UPDATE: You also say "I am dealing with threads". In that case, it's possible that a data race could cause one thread to call the function while another is still constructing the object - again, giving undefined behaviour. You need to make sure all data accesses are correctly synchronised.
It's OK, just missing semicolons after the class declarations.
Add return type to the Derived method. Also add semicolons after class definitions
You are missing the return type for f and ; after class definitions
Change your code to
class Base
{
protected:
virtual int f(void) = 0;
};
class Derived : public Base
{
public:
int f(void);
};
int Derived::f(void)
{
// do something here
}
Further, post runnable code if possible. Iow add
int main()
{
Derived d;
d.f();
}
to your code sample
Make all your functions in your two classes public. And why are you declaring int i? it's not used at all.
you need to declare
class Derived : public Base
{
protected:
virtual int f(void);
}
I suppose your pure virtual function call comes from Base class using f in another of it's methods.
You'll have to forgive me if this is a really basic question; I haven't used C++ this much in a long time so I've forgotten how a lot of it works.
Anyway, I have a base class and a couple derived classes like this (super oversimplified, but the gist is the same):
class Base
{
public:
Base () { }
int SomeFunction (int x, int y); // abstract definition
};
class Derived1 : public Base
{
public:
Derived1() : Base() { }
int SomeFunction (int x, int y)
{
// actual implementation
return 4;
}
};
class Derived2 : public Base
{
public:
Derived2() : Base() { }
int SomeFunction (int x, int y)
{
// actual implementation
return 7;
}
};
Later on in main I have a list of Base objects:
Base *baseobjects[10];
Later I fill that array with instances of Derived1 and Derived2. That works with baseobjects[i] = &newDerived1 (where newDerived1 is an instance of the Derived1 class). That's all fine.
What I can't seem to figure out is how to later iterate through the baseobjects array and call SomeFunction on every instance in the list without explicitly knowing which derived class I'm using. I've done this in C# and it works fine, but apparently my C++ syntax is off:
int result = baseobjects[i]->SomeFunction(a, b);
That gives me a LNK2019 error when I try to compile, apparently because it's looking at the Base class for the implementation and it isn't there. I'm assuming I have to use some pointer tricks to get it to look at the proper derived method, but nothing I've tried yet has worked. Any suggestions?
Your method should be declared virtual. And in your case, probably pure virtual.
class Base
{
public:
Base () { }
virtual int SomeFunction (int x, int y) = 0; // abstract definition
};
Note that, while this is not absolutely required, you might as well declare a virtual destructor. Do it if you ever delete a derived instance trough a pointer of the base class.
class Base
{
public:
//Base () {} // This is not required, the default provided constructor is similar.
virtual ~Base() {} // virtual destructor.
virtual int SomeFunction (int x, int y) = 0; // abstract definition
};
Edit:
Also, regarding the link error you posted:
Either you forgot the = 0, either you are calling Base::SomeFunction() from somewhere.
As Thomas Edleson points out, = 0 does not mean that your function has no implementation: it can have one, but it only requires the derived classes to (re)implement it to not being abstract.
If you are interested in this topic, I suggest you read this post.
If you want to override a method, it must be virtual.
class Base
{
public:
Base () { }
virtual int SomeFunction (int x, int y); // abstract definition
}
Seccond thing is that your derivated classes did not extends of your base-class.
class Derived1 : public Base
{
public:
Derived1() : Base() { }
int SomeFunction (int x, int y)
{
// actual implementation
return 4;
}
}
You have to declare the member function SomeFunction()
virtual
abstract
So the declaration for Base should look like this:
class Base
{
public:
Base() { }
virtual int SomeFunction(int x, int y) = 0;
};
You can omit the virtual keyword in the derived classes.
To just slightly elaborate on ereOn's answer, you do need to declare you base class function (ie: your abstract definition) in order for your derived classes to be able to override it. What he didn't clarify though is that other than that, what you've posted is fine (that is, the calls to the function you posted will then work without any modification).
Note also, that if you're after a pure abstract definition, you should append = 0 to your function declaration as follows:
class Base
{
public:
Base () { }
virtual int SomeFunction (int x, int y) = 0; // pure abstract definition
};
This lets the compiler know that classes derived from Base must supply their own implementation of SomeFunction.
Update: This issue is caused by bad memory usage, see solution at the bottom.
Here's some semi-pseudo code:
class ClassA
{
public:
virtual void VirtualFunction();
void SomeFunction();
}
class ClassB : public ClassA
{
public:
void VirtualFunction();
}
void ClassA::VirtualFunction()
{
// Intentionally empty (code smell?).
}
void ClassA::SomeFunction()
{
VirtualFunction();
}
void ClassB::VirtualFunction()
{
// I'd like this to be called from ClassA::SomeFunction()
std::cout << "Hello world!" << endl;
}
The C# equivalent is as follows: Removed C# example, as it's not relevant to the actual problem.
Why isn't the ClassB::VirtualFunction function being called when called from ClassA::SomeFunction? Instead ClassA::VirtualFunction is being called...
When I force implementation of the virtual function ClassA::VirtualFunction, like so:
class ClassA
{
public:
virtual void VirtualFunction() = 0;
void SomeFunction();
}
class ClassB : public ClassA
{
public:
void VirtualFunction();
}
void ClassA::SomeFunction()
{
VirtualFunction();
}
void ClassB::VirtualFunction()
{
// I'd like this to be called from ClassA::SomeFunction()
std::cout << "Hello world!" << endl;
}
The following error occurs at runtime, despite the derrived function deffinately being declared and defined.
pure virtual method called
terminate called without an active exception
Note: It seems like the error can be caused even by bad memory usage. See self-answer for details.
Update 1 - 4:
Comments removed (not releavnt).
Solution:
Posted as an answer.
class Base {
public:
virtual void f() { std::cout << "Base" << std::endl; }
void call() { f(); }
};
class Derived : public Base {
public:
virtual void f() { std::cout << "Derived" << std::endl; }
};
int main()
{
Derived d;
Base& b = d;
b.call(); // prints Derived
}
If in the Base class you do not want to implement the function you must declare so:
class Base {
public:
virtual void f() = 0; // pure virtual method
void call() { f(); }
};
And the compiler won't allow you to instantiate the class:
int main() {
//Base b; // error b has a pure virtual method
Derived d; // derive provides the implementation: ok
Base & b=d; // ok, the object is Derived, the reference is Base
b.call();
}
As a side note, be careful not to call virtual functions from constructors or destructors as you might get unexpected results.
If you're getting that 'pure virtual method called
terminate called without an active exception' error message, that means you're calling the virtual function from the constructor or destructor of classA (the base class), which you should not do.
on the pure virtual method called error:
You should create a different question as it is in fact different than the other. The answer to this question is on the very last paragraph of my previous answer to your initial question:
Do not call virtual functions from constructors or destructors
class Base
{
public:
Base() { f(); }
virtual void f() = 0;
};
class Derived : public Base
{
public:
virtual void f() {}
};
int main()
{
Derived d; // crashes with pure virtual method called
}
The problem in the code above is that the compiler will allow you to instantiate an object of type Derived (as it is not abstract: all virtual methods are implemented). The construction of a class starts with the construction of all the bases, in this case Base. The compiler will generate the virtual method table for type Base, where the entry for f() is 0 (not implemented in base). The compiler will execute the code in the constructor then. After the Base part has completely been constructed, construction of the Derived element part starts. The compiler will change the virtual table so that the entry for f() points to Derived::f().
If you try calling the method f() while still constructing Base, the entry in the virtual method table is still null and the application crashes.
When A calls VirtualFunction() it will automatically call the version on B. That is the point of virtual functions.
I am not as familiar with the C++ syntax tho. Do you have to declare the function to be virtual at the point of the body as well as in the header?
Alsop, in class B you probably need to mark it as override
in C# its easy. I just don't know the c++ syntax.
public class ClassA
{
public **virtual** void VirtualFunction(){}
public void FooBar()
{
// Will call ClassB.VirtualFunction()
VirtualFunction();
}
}
public class ClassB
{
public **overide** void VirtualFunction()
{
// hello world
}
}
If you want to force the derived classes to implement the VirtualFunction:
class ClassA
{
public:
virtual void VirtualFunction()=0;
void SomeFunction();
}
This is C++. Default the derived function will be called.
If you want to call the base-class function do:
void ClassA::SomeFunction()
{
// ... various lines of code ...
ClassA::VirtualFunction();
}
There's nothing wrong with your code but your sample is incomplete. You do not state where you are calling SomeFunction from.
As has already been pointed out by dribeas you must be careful calling virtual functions from your constructor as the virtual tables are only built up as each class in the hierarchy completes construction.
Edit: The following paragraph of my reply was incorrect. Apologies. It is fine to call SomeFunction from the constructor of ClassB as the vtable is in place (at least) by the end of the initialiser list i.e. once you are in the body of the constructor. It is not fine to call it from ClassA's constructor of course.
Original paragraph:
I suspect you must be calling SomeFunction from the constructor of ClassB at which point only the vtable up to type ClassA will be complete i.e. to the virtual dispatch mechanism your class is still of type ClassA. It only becomes an object of type ClassB when the constructor completes.
To call a virutal function function you need to call via a pointer or a reference.
void ClassA::SomeFunction()
{
VirtualFunction(); // Call ClassA::VirtualFunction
this->VirtualFunction(); // Call Via the virtual dispatch mechanism
// So in this case call ClassB::VirtualFunction
}
You need to be able to distinguish the two different types of call otherwise the classA::VirtualFunction() becomes inaccessible when it is overridden.
As pointed out by others if you want to make the base class version abstract then use the = 0 rather than {}
class A
{
virtual void VirtualFunction() =0;
....
But sometimes it is legitimate to have an empty definition. This will depend on your exact usage.
You aren't defining the function in ClassB correctly, it should be:
public class ClassB
{
public void override AbstractFunction()
{
// hello world
}
}
Then, any call from the base class to virtual/abstract methods will call the implementation on the derived instance.