Calling derived class function from base class - c++

class base
{
public:
virtual void start();
virtual void stop();
void doSomething() { start(); .... stop(); }
}
class derived : public base
{
public:
void start();
void stop();
}
But when I call doSomething() in the derived class it is using it's own definition of Start() and Stop() - not the derived ones.
I don't want to rewrite doSomething() in the derived class because it would be identical to the base one. What am I doing wrong?
Sorry if that wasn't clear.
The behaviour of Start() and Stop() in the derived class is different (it's a different machine) - but I want to use the original base class doSomething() because that hasn't changed. It just has to start() and stop() using the new derived class code.

The code you've posted should work the way you want. Calling doSomething on an instance of derived will call the overridden start and stop functions defined in derived.
There's an exception to that, though. If you call doSomething in the constructor or destructor of base (whether directly or indirectly), then the versions of start and stop that get called will be the ones defined in base. That's because in those circumstances, you don't actually have a valid derived instance yet. It's either not fully constructed or partially destructed, so the language prevents you from calling methods that would use the partial object.
If you're not calling it from a base constructor or destructor, then there is more to the problem than what's shown here.

Update
Based on your comment below that you are trying to make doSomething() call the Derived class's version of start() and stop(), my updated answer to your question is as follows:
There is nothing wrong with the way that you defined Base and Derived. You are probably experiencing what is called "code slicing", where you are calling "doSomething()" on an object whose declared type is "Base", instead of "Base*" or "Base&", which will result in the object being converted to type Base.
Bad example:
Derived derived;
Base base = derived;
base.doSomething(); // This is Base's version of doSomething()
Good example:
Base* base = new Derived; // NOTE: declared type is "Base*"
base->doSomething(); // This will call Derived version
delete base;
Side-note: you should use a scoped_ptr, shared_ptr, unique_ptr, or some other smart pointer class instead of using a pointer directly as in my example; however, to not obscure the issue, I have opted to use a raw pointer in this example. For more information about "slicing", see:
What is the slicing problem in C++? - StackOverflow
Slicing in C++
Original solution
You could do something like this:
class Base {
public:
Base() {}
virtual ~Base() {}
virtual void start() {
startInternal();
}
virtual void stop() {
stopInternal();
}
void doSomething() {
startInternal();
// ...
stopInternal();
}
private:
void startInternal() {
// ...
}
void stopInternal() {
// ...
}
};
class Derived : public Base {
public:
Derived() {}
virtual ~Derived() {}
virtual void start() {
// ...
}
virtual void stop() {
// ...
}
};
If you do this, then doSomething() will use the internal version of start/stop which isn't overridden. You will find this pattern a lot, when a constructor/destructor needs to share logic with a virtual method.
Also, not related to the issue at hand, don't forget that you should always create a virtual destructor whenever you create a class that has virtual methods.

Related

Do method calls in derived classes count as virtual function calls?

Say I have an abstract base class and a derived class like so,
class Base {
public:
virtual void doSomething() = 0;
}
class Derived: public Base {
private:
void doSomethingSpecificA();
void doSomethingSpecificB();
public:
void doSomething();
}
and I initialize my derived class with
Base *instance = new Derived;.
Now, say I call the derived version of doSomething like:
instance->doSomething();
and doSomething() calls the private methods doSomethingSpecificA() and doSomethingSpecificB(). Do these internal calls to the specific functions require the same amount of vtable work that the original call to doSomething() required? Or are they equivalent to just a standard method call?
Do these internal calls to the specific functions require the same amount of vtable work that the original call to doSomething() required?
No. There is no lookup/dynamic dispatch involved in the calls to doSomethingSpecificA and doSomethingSpecificB since they are not virtual member functions.
Or are they equivalent to just a standard method call?
Yes.

How to clean up resources that have been allocated by a virtual member function

Let's say I have the following code:
class BaseMember
{
};
class DerivedMember : public BaseMember
{
};
class Base
{
private:
BaseMember* mpMember;
protected:
virtual BaseMember* initializeMember(void)
{
return new BaseMember[1];
}
virtual void cleanupMember(BaseMember* pMember)
{
delete[] pMember;
}
public:
Base(void)
: mpMember(NULL)
{
}
virtual ~Base(void)
{
cleanupMember(mpMember);
}
BaseMember* getMember(void)
{
if(!mpMember)
mpMember = initializeMember();
return mpMember;
}
};
class Derived : public Base
{
protected:
virtual BaseMember* initializeMember(void)
{
return new DerivedMember;
}
virtual void cleanupMember(BaseMember* pMember)
{
delete pMember;
}
};
Base and BaseMember are parts of an API and may be subclassed by the user of that API, like it is done via Derived and DerivedMember in the example code.
Base initializes mpBaseMember by a call to it's virtual factory function initializeMember(), so that the derived class can override the factory function to return a DerivedMember instance instead of a BaseMember instance.
However, when calling a virtual function from within a base class constructor, the base implementation and not the derived class override gets called.
Therefor I am waiting with the initialization of mpMember until it gets accessed for the first time (which of course implies, that the base class and any derived class, that may could get derived further itself, are not allowed to access that member from inside the constructor).
Now the problem is: Calling a virtual member function from within the base base destructor will result in a call of the base class implementation of that function, not of the derived class override.
That means that I can't simply call cleanupMember() from within the base class destructor, as that would call it's base class implementation, which may not be able to correctly cleanup the stuff, that the derived implementation of initializeMember() has initialized.
For example the base class and the derived class could use incompatible allocators that may result in undefined behavior when getting mixed (like in the example code - the derived class allocates the member via new, but the base class uses delete[] to deallocate it).
So my question is, how can I solve this problem?
What I came up with is:
a) the user of the API has to explicitly call some cleanup function before the Derived instance gets destructed. That can likely be forgotten.
b) the destructor of the (most) derived class has to call a cleanup function to cleanup stuff which initialization has been triggered by the base class. That feels ugly and not well designed as ownership responsibilities are mixed up: base class triggers allocation, but derived class has to trigger deallocation, which is very counter-intuitive and can't be known by the author of the derived class unless he reads the API documentation thoroughly enough to find that information.
I would really like to do this in a more fail-proof way than relying on the users memory or his reliability to thoroughly read the docs.
Are there any alternative approaches?
Note: As the derived classes may not exist at compile time of the base classes, static polymorphism isn't an option here.
What about a modification of the factory pattern that would include the cleanup method? Meaning, add a attribute like memberFactory, an instance of a class providing creation, cleanup, as well as access to the members. The virtual initialization method would provide and initialize the right factory, the destructor ~Base would call the cleanup method of the factory and destruct it.
(Well, this is quite far from the factory pattern... Perhaps it is known under another name?)
If you really want to do this sort of thing you can do it like this:
class Base {
BaseMember* mpMember;
protected:
Base(BaseMember *m) : mpMember(m) {}
virtual void doCleanupMember(BaseMember *m) { delete [] m; }
void cleanupMember() {
// This gets called by every destructor and we only want
// the first call to do anything. Hopefully this all gets inlined.
if (mpMember) {
doCleanupMember(pmMember);
mpMember = nullptr;
}
}
public:
Base() : mpMember(new BaseMember[1]) { }
virtual ~Base(void) { cleanupMember(); }
};
class Derived : public Base {
virtual void doCleanupMember(BaseMember *m) override { delete m; }
public:
Derived() : Base(new DerivedMember) {}
~Derived() { cleanupMember(); }
};
However there are reasons this is a bad idea.
First is that the member should be owned an exclusively managed by Base. Trying to divide up responsibility for Base's member into the derived classes is complicated and just asking for trouble.
Secondly the ways you're initializing mpMember mean that the member has a different interface depending on who initialized it. Part of the problem you've already run into is that the information on who initialized the member has been destroyed by the type you get to ~Base(). Again, trying to have different interfaces for the same variable is just asking for trouble.
We can at least fix the first problem by using something like shared_ptr which lets up specify a deleter:
class Base {
std::shared_ptr<BaseMember> mpMember;
public:
Base(std::shared_ptr<BaseMember> m) : mpMember(m) { }
Base() : mpMember(std::make_shared<BaseMember>()) { }
virtual ~Base() {}
};
class Derived : virtual public Base {
public:
Derived()
: Base(std::shared_ptr<BaseMember>(new DerivedMember[1],
[](BaseMember *m){delete [] m;} ) {}
};
This only hides the difference in the destruction part of the member's interface. If you had an array of more elements the different users of the member would still have to be able to figure out if mpMember[2] is legal or not.
First of all, you must use RAII idiom when developing in C++. You must free all your resources in destructor, of course if you don't wish to fight with memory leaks.
You can create some cleanupMember() function, but then you should check your resources in destructor and free them if they are not deleted (as cleanupMember can be never called, for example because of an exception). So add destructor to your derived class:
virtual ~Derived()
{
Derived::cleanupMember(mpMember);
}
and manage the member pointer in the class itself.
I also recommend you to use smart pointers here.
Never never never call virtual methods in constructor/destructor because it makes strange results (compiler makes dark and weird things you can't see).
Destructor calling order is child and then parent
You can do like this (but there is probalby a better way) :
private:
// private destructor for prevent of manual "delete"
~Base() {}
public:
// call this instead use a manual "delete"
virtual void deleteMe()
{
cleanupMember(mpMember);
delete this; // commit suicide
}
More infos about suicide :
https://stackoverflow.com/a/3150965/1529139 and http://www.parashift.com/c++-faq-lite/delete-this.html
PS : Why destructor is virtual ?
Let mpMember be protected and let it be initialized in derived class constructor and deallocated in derived destructor.
Inspired by the ideas from https://stackoverflow.com/a/19033431/404734 I have come up with a working solution :-)
class BaseMember
{
};
class DerivedMember : public BaseMember
{
};
class BaseMemberFactory
{
public:
virtual ~BaseMemberFactory(void);
virtual BaseMember* createMember(void)
{
return new BaseMember[1];
}
virtual void destroyMember(BaseMember* pMember)
{
delete[] pMember;
}
};
class DerivedMemberFactory : public BaseMemberFactory
{
virtual BaseMember* createMember(void)
{
return new DerivedMember;
}
virtual void destroyMember(BaseMember* pMember)
{
delete pMember;
}
};
class Base
{
private:
BaseMemberFactory* mpMemberFactory;
BaseMember* mpMember;
protected:
virtual BaseMemberFactory* getMemberFactory(void)
{
static BaseMemberFactory fac;
return &fac;
}
public:
Base(void)
: mpMember(NULL)
{
}
virtual ~Base(void)
{
mpMemberFactory->destroyMember(mpMember);
}
BaseMember* getMember(void)
{
if(!mpMember)
{
mpMemberFactory = getMemberFactory();
mpMember = mpMemberFactory->createMember();
}
return mpMember;
}
};
class Derived : public Base
{
protected:
virtual BaseMemberFactory* getMemberFactory(void)
{
static DerivedMemberFactory fac;
return &fac;
}
};

Virtual function call from a normal function

class base
{
public:
void virtual func(){cout<<"base";}
void check()
{
func();
}
};
class derived: public base
{
public:
void func(){cout<<"dervied";}
};
int main()
{
base *obj = new derived();
obj->check();
return 0;
}
Above code prints derived on the console.
Now, I understand the concept of virtual functions but I'm unable to apply it here. In my understanding whenever we call a virtual function, compiler modifies the call to "this->vptr->virtualfunc()" and that's how most heavily derived's class function gets invoked. But in this case, since check() is not a virtual function, how does the compiler determine that it needs to invoke func() of derived?
how does the compiler determine that it needs to invoke func() of derived?
In the same exat way - by invoking this->vptr->virtualfunc(). Recall that this belongs to the derived class even inside the base class, because each derived class is a base class as well, so the same way of accessing virtual functions works for it too.
Exactly the way you said, by using the vptr in the class member. It knows the function is virtual, therefore it knows it has to call it through the virtual function table.

Invoke abstract method in super class, and implement it in subclass in C++?

In Java it's possible to write an abstract, super class with unimplemented, abstract methods and non-abstract methods which invoke the abstract methods. Then in the subclass are the abstract methods implemented. When you then make an instance of the subclass, the super class uses the implementations in the subclass. How do I accomplish this in C++?
Here is what I mean, but in Java:
SuperClass.java
public abstract class SuperClass {
public SuperClass() {
method();
}
private void method() {
unimplementedMethod();
}
protected abstract void unimplementedMethod();
}
SubClass.java
public class SubClass extends SuperClass {
public SubClass() {
super();
}
#Override
protected void unimplementedMethod() {
System.out.println("print");
}
public static void main(String[] args) {
new SubClass();
}
}
Would be awesome if you showed me how this is accomplished in C++. :)
In general, what you are looking for, is the virtual keyword. In a nutshell virtual declares the intent that this method can be overriden. Note that such a method can still have an implementation- virtual just makes it overrideable. To declare an "abstract method", you can say declare intent of please provide an implementation in the derived class with = 0, as shown below. Such methods are called pure virtual in C++.
However, there are some caveats that you should watch out for. As pointed out in a comment below, you were calling method() from within the SuperClass constructor. Unfortunately this is not possible in C++, due to the order in which objects are constructed.
In C++ a derived class constructor immediately calls it's superclass constructor before allocating its members or executing the body of the constructor. As such, the members of the base class are constructed first, and the derived class' members are constructed last. Calling a virtual method from a base class will not work as you expect in Java, since the derived class has not been constructed yet, and thus the virtual methods have not been redirected to the derived implementations yet. Hope that makes sense.
However, calling method() on a SuperClass object after creation will work as you expect: it would call the virtual function which would output "print".
class SuperClass {
public:
SuperClass() {
// cannot call virtual functions from base constructor.
}
virtual ~SuperClass() { } // destructor. as Kerrek mentions,
// classes that will be inherited from,
// should always have virtual destructors.
// This allows the destructors of derived classes
// to be called when the base is destroyed.
private:
void method() {
unimplementedMethod();
}
protected:
virtual void unimplementedMethod() = 0; // makes method pure virtual,
// to be implemented in subclass
}
SubClass.h
class SubClass : public SuperClass {
public:
SubClass() : SuperClass() { // how the superclass constructor is called.
}
// no need for "override" keyword, if the methd has the same name, it will
// automatically override that method from the superclass
protected:
void unimplementedMethod() {
std::cout << "print" << std::endl;
}
}
In C++, you should never call virtual functions in the constructor, so it doesn't work quite as literally. Best to use a separate member function
class SuperClass
{
public:
void action() { method(); } // not in the constructor, please
virtual ~SuperClass() { } // always a virtual destructor when polymorphic
protected:
void method() { unimplementedMethod(); }
private:
virtual void unimplementedMethod() = 0;
};
class SubClass : public SuperClass
{
private:
virtual void unimplementedMethod() { std::cout << "print" << std::endl; }
// no need to spell out the next couple of functions, but for your entertainment only
public:
SubClass() : SuperClass() { }
virtual ~SubClass() { }
};
Now to invoke:
int main()
{
SuperClass * p = new SubClass; // construct first...
p->action(); // ... then invoke, after construction is complete
delete p; // thank god for that virtual destructor!
}
The base constructor runs before the derived class is constructed, so you cannot call any derived functions in the base constructor, and in particular you cannot call any pure-virtual functions.
Note that you have the private and protected the wrong way round: The non-virtual accessor function should be protected so it can be used in the entire class hierarchy, but the virtual implementation function should be private, since it only needs to be seen by the accessor function in the same class. In a nutshell: protected-nonvirtual and private-virtuals.
(The usage example is a bit contrived, since you wouldn't normally use new or raw pointers in C++.)
In C++ these are called pure virtual functions/methods.
Basically you tack a "=0" at the end of a method:
virtual doSomething() = 0; // pure virtual
Search around SO for "c++ pure virtual" and you'll find tons of answers.
You need to use virtual methods. The implementation works like this:
/* here's MyBaseClass.h */
class MyBaseClass
{
public:
MyBaseClass(void);
~MyBaseClass(void);
void MyMethod();
protected:
virtual void MyUnimplementedMethod() = 0;
};
/* here's MyIneritedClass.h */
class MyInheritedClass :
public MyBaseClass
{
public:
MyInheritedClass(void);
~MyInheritedClass(void);
protected:
virtual void MyUnimplementedMethod();
};
/* here's the implementation of the method in the base class */
void MyBaseClass::MyMethod()
{
MyUnimplementedMethod();
}
/* and here's the implementation of the abstract method in the derived */
void MyInheritedClass::MyUnimplementedMethod()
{
_tprintf(L"Hello, world");
}
You declare the method as virtual:
snippet:
class Parent{
public:
virtual int methodA() {return methodB();}; // calls the abstract method
virtual int methodB() = 0; // "=0" means pure virtual, not implemented in the base
}
class Child : public Parent{
public:
virtual int methodB() { /* implementation */}
}
virtual means the child may override the implementation and the parent should be then calling the overriden implementation. Adding "=0" to the declaration of the virtual method makes it pure virtual, i.e.: the base doesn't have an implementation of its own, and relies on the implementation by the child. Such class cannot be instantiated (i.e.: abstract class).

Why might my virtual function call be failing?

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.