a more exact version of the code is:
class SomeParam;
class IBase
{
public:
virtual void Func(SomeParam* param = NULL)
{
cout << "Base func";
}
};
class DerivedA : public IBase
{
public:
void Func()
{
//do some custom stuff
cout << "DerivedA func";
IBase::Func();
}
};
class DerivedB : public IBase
{
public:
void Func()
{
//do some custom stuff
cout << "DerivedB func";
IBase::Func();
}
};
//at somewhere else
void FuncCaller(IBase *instance1, IBase *instance2)
{
IBase *i1 = instance1;
IBase *i2 = instance2;
i1->Func();
i2->Func();
}
DerivedA *a = new DerivedA;
DerivedB *b = new DerivedB;
FuncCaller(a,b);
This gives me:
"Base func"
"Base func"
It looks like you have provided a simplified version of your code to make it more readable, but you have oversimplified inadvertently.
The most likely reasons for your behaviour are:
Slicing in FuncCaller() (see quamrana's answer for the details)
Wrong overriding, such as making the derived class function const, while the base class function is not const
EDIT: After reading the edited question, it is clearly the second reason. You are not overriding the base class function, but hiding it in the derived classes with a new definition. You need to keep exactly the same signature (covariance does not apply here, since the function returns void) in the derived classes. In code, you need to do either:
class SomeParam;
class IBase
{
public:
virtual void Func(SomeParam* param = NULL)
{
cout << "Base func";
}
};
class DerivedA : public IBase
{
public:
void Func(SomeParam* param = NULL)
{
//do some custom stuff
cout << "DerivedA func";
IBase::Func();
}
};
class DerivedB : public IBase
{
public:
void Func(SomeParam* param = NULL)
{
//do some custom stuff
cout << "DerivedB func";
IBase::Func();
}
};
//at somewhere else
void FuncCaller(IBase *instance1, IBase *instance2)
{
IBase *i1 = instance1;
IBase *i2 = instance2;
i1->Func();
i2->Func();
}
DerivedA *a = new DerivedA;
DerivedB *b = new DerivedB;
FuncCaller(a,b);
or
class SomeParam;
class IBase
{
public:
virtual void Func()
{
cout << "Base func";
}
};
class DerivedA : public IBase
{
public:
void Func()
{
//do some custom stuff
cout << "DerivedA func";
IBase::Func();
}
};
class DerivedB : public IBase
{
public:
void Func()
{
//do some custom stuff
cout << "DerivedB func";
IBase::Func();
}
};
//at somewhere else
void FuncCaller(IBase *instance1, IBase *instance2)
{
IBase *i1 = instance1;
IBase *i2 = instance2;
i1->Func();
i2->Func();
}
DerivedA *a = new DerivedA;
DerivedB *b = new DerivedB;
FuncCaller(a,b);
I found the reason:
The overriden virtual functions also must have a default parameter like Base's.like:
class DerivedB : public IBase
{
public:
void Func(SomeParam* param=NULL)
{
//do some custom stuff
cout << "DerivedB func";
IBase::Func();
}
};
Thanks for the answers guys.
Your virtual function is not overridden.
Your supposedly "virtual" methods in the derived classes have different signatures. The method in the base class has one parameter, while the methods in the derived classes have no parameters. Because of this, the methods in the derived classes are completely unrelated to the base class method. They don't override the base class method. This is why the base class method is always called.
I've tried a copy of the code you posted on VS2008 and it works fine.
I can only suggest that your actual code is more like:
void FuncCaller(IBase instance)
{
instance.Func();
}
void Funcs()
{
DerivedA *a = new DerivedA;
DerivedB *b = new DerivedB;
FuncCaller(*a);
FuncCaller(*b);
}
where FuncCaller slices the base part off the derived instances.
Related
I have a base class and a number of generations of descendants (derived classes):
class Base{
public:
virtual void myFunc() = 0;
}
class Derived : public Base{
//This class needs to implement myFunc()
}
class Derived2 : public Derived{
//How to force this class to implement its version of myFunc(), and force it to call Derived::myFunc as well ?
}
class Derived3 : public Derived2{
//.....should implement its own myFunc and call Derived2's mynFunc()...
}
class Derived4 : public Derived3{
//.....should implement its own myFunc and call Derived3's mynFunc()...
}
Is there a pattern to ensure:
That each derived class (regardless of whether it is an immediate descendant of the base class, or a descendant of a descendant of the base class), implement its version of myFunc?
That each derived class calls its immediate parent class myFunc?
EDIT: The pattern that comes to mind to me is Decorator pattern, but wondering if there is some better way or variation.
I propose the following solution:
#include <iostream>
template <class BaseClass>
class RequireMyFunc: public BaseClass
{
public:
virtual void myFunc() = 0; // declaration to force write implementation
protected:
void callBaseClassMyFunc() override
{
BaseClass::callBaseClassMyFunc();
BaseClass::myFunc();
}
};
class Base{
public:
void func()
{
callBaseClassMyFunc();
//myFunc();
}
virtual void myFunc(){};
protected:
Base(){}
virtual void callBaseClassMyFunc(){};
};
class Derived : public RequireMyFunc<Base>{
public:
void myFunc() override
{
std::cout << "Derived" << std::endl;
}
};
class Derived2 : public RequireMyFunc<Derived>{
public:
void myFunc() override
{
std::cout << "Derived2" << std::endl;
}
};
class Derived3 : public RequireMyFunc<Derived2>{
public:
void myFunc() override
{
std::cout << "Derived3" << std::endl;
}
};
int main()
{
Base* d = new Derived();
d->func(); // prints "Derived" (invokes only Derived::myFunc)
Base* d2 = new Derived2();
d2->func(); // prints "Derived" and "Derived2", i.e. invokes Derived::myFunc and Derived2::myFunc
Base* d3 = new Derived3();
d3->func(); // prints "Derived", "Derived2" and "Derived3"
d->myFunc(); // prints "Derived"
d2->myFunc(); // prints only "Derived2"
d3->myFunc(); // prints only "Derived3"
// Base* b = new Base(); -- cannot create because of protected constructor
//b->myFunc(); // prints nothing
}
So I have a vector of base classes and a couple bugs in my code, which means that I need to know which derived class is calling the polymorphic method:
class Base {
virtual void render() {}
}
class Derived1 {
void render() override {/*do stuff*/}
}
class Derived2 {
void render() override {/*do stuff*/}
}
class Game {
std::vector<Base> baseVec;
void render() {
for(Base b: baseVec) {
b.render();
//std::cout << typeid(b).name() << std::endl; prints base class' name, and requires some logic to unmangle the actual name
//std::cout << std::type_index(typeid(b)).name() << std::endl; also prints base class' name
//std::cout << typeNames[std::type_index(typeid(b))] << std::endl; typeNames is an unordered_map<std::type_index, std::string> - still prints the base class' name, and the list has to be punched in by hand (bad)
}
}
}
Below code is modified for your requirement as per my understanding for your requirements:
class Base {
public:
virtual void render() = 0;
};
class Derived1: public Base {
void render() override { std::cout << "Derived1"<<std::endl; }
};
class Derived2: public Base {
void render() override { std::cout << "Derived2" << std::endl; }
};
int main()
{
std::vector<Base*> baseVec;
Derived1 d;
Derived2 d1;
baseVec.push_back(&d);
baseVec.push_back(&d1);
for (auto& b : baseVec)
{
b->render();
std::cout << typeid(*b).name() << std::endl;
}
return 0;
}
Output:
Derived1
class Derived1
Derived2
class Derived2
The typeid is solving your name by using=> typeid(*b).name().
typeid explained
I have two base classes and a class that inherits both base classes.
Both base classes have a virtual function with the same signature, and I want to provide different implementations in the derived class to each virtual function.
class A{
virtual void f() = 0;
}
class B{
virtual void f() = 0;
}
class Derived:public A, public B{
void A::f() override{ // Error
...
}
void B::f() override{ // Error
...
}
}
What is the correct way to do this? (I cannot rename the virtual function. Actually the two base classes are generated from the same template class.)
template <typename T>
class AShim : public A {
void f() override {
static_cast<T*>(this)->A_f();
}
};
template <typename T>
class BShim : public B {
void f() override {
static_cast<T*>(this)->B_f();
}
};
class Derived: public AShim<Derived>, public BShim<Derived> {
void A_f();
void B_f();
};
class A {
public:
virtual void f() = 0;
};
class B {
public:
virtual void f() = 0;
};
class Derived :public A, public B {
public:
void A::f() {
cout << "Inside A's version"<<endl;
}
void B::f() {
cout << "Inside B's version"<<endl;
}
};
int main()
{
Derived derived;
cout << "calling A" << endl;
A *a;
a = &derived;
a->f();
cout << "calling B" << endl;
B *b;
b = &derived;
b->f();
}
Works fine for me. No need to explicitly mention override keyword as pure virtual functions will be overridden by virtue of its default properties.Use base class's scope while defining the functions as you have already done. Use public access specifier to enable derived classes to override the pure virtual function. That's all.
I recently wanted to get c++ to dynamically resolve a member/function by its input parameter which comes in some derived versions. Here is what I mean:
#include <iostream>
class Base {
};
class DerivedA : public Base {
};
class DerivedB : public Base {
};
class DerivedC : public Base {
};
class Test {
public:
void world( DerivedA *instance )
{
std::cout << "DerivedA" << std::endl;
}
void world( DerivedB *instance )
{
std::cout << "DerivedB" << std::endl;
}
void world( Base *instance )
{
std::cout << "Base" << std::endl;
}
};
int main()
{
Base *a = new Base;
Base *b = new DerivedA;
Base *c = new DerivedB;
Base *d = new DerivedC;
Test hello;
hello.world( a );
hello.world( b );
hello.world( c );
hello.world( d );
return 0;
}
The behaviour I WANTED is this:
Base
DerivedA
DerivedB
Base
But for sure the output I am REALLY getting is this:
Base
Base
Base
Base
I understand, that dynamic binding is the other way, resolving the correct member function within the derived classes of base and not like that way - but can it work in any way for that?
Maybe I am only missing the essential point..
However, many thanks in advance!
Sebastian
The type of a, b, c and d are all Base*. The compiler does not track "what the variable contains". If that is what you want to do then you need to use a virtual function in the class that you derive from, for example:
class Base {
public:
virtual const char* MyName() { return "Base"; }
};
class DerivedA : public Base {
public:
virtual const char* MyName() { return "DerivedA"; }
};
... similiar for all derived classes ...
void world( Base *instance )
{
std::cout << instance->MyName() << std::endl;
}
(Edit: To get exactly the behaviour you list in the first case, you'd need to NOT implement the MyName() function in the DerivedC class)
So, using a wrapper class may be the solution for a test-setup. Here's something I just hacked up, without much consideration and sophistication:
#include <iostream>
class Base {
};
class DerivedA : public Base {
};
class DerivedB : public Base {
};
class DerivedC : public Base {
};
class Test {
public:
void world( DerivedA *instance )
{
std::cout << "DerivedA" << std::endl;
}
void world( DerivedB *instance )
{
std::cout << "DerivedB" << std::endl;
}
void world( Base *instance )
{
std::cout << "Base" << std::endl;
}
};
template<typename T>
class Wrapper
{
public:
Wrapper(T* i) : instance(i)
{
}
~Wrapper()
{
delete instance;
}
void doTest(Test& t)
{
t.world(instance);
}
T* instance;
};
int main()
{
Test hello;
Wrapper<Base> a(new Base);
Wrapper<DerivedA> b(new DerivedA);
Wrapper<DerivedB> c(new DerivedB);
Wrapper<DerivedC> d(new DerivedC);
a.doTest(hello);
b.doTest(hello);
c.doTest(hello);
d.doTest(hello);
return 0;
}
In your example you don't have a runtime polymorphism scheme (i.e., dynamic binding). What you have is an overloaded member function and in overload resolution the compiler correctly selects void world( Base *instance ).
In order to get what you want you should apply an inheritance scheme like the one below:
class Base {
public:
virtual ~Base() {}
virtual void world() const { std::cout << "Base" << std::endl; }
};
class DerivedA : public Base {
public:
virtual ~DerivedA() {}
void world() const { std::cout << "DerivedA" << std::endl; }
};
class DerivedB : public Base {
public:
virtual ~DerivedB() {}
void world() const { std::cout << "DerivedB" << std::endl; }
};
class DerivedC : public Base {
public:
virtual ~DerivedC() {}
using Base::world;
};
Live Demo
Edit:
In order to keep your code as intented in one place you could add to the above scheme the following altered version of the Test class:
class Test {
public:
void world( DerivedA *instance ) { instance->world(); }
void world( DerivedB *instance ) { instance->world(); }
void world( Base *instance ) { instance->world(); }
};
Live Demo
Unfortunately, overload resolution takes place at compile time whereas dynamic-dispatching takes place at run-time. Thus, if you intended for the compiler to deduce the underlying type from a Base pointer and then pick-up the right member function from Test class, this is not feasible.
Is it possible to access a base class function which has the same signature as that of a derived class function using a derived class object?. here's a sample of what I'm stating below..
class base1 {
public:
void test()
{cout<<"base1"<<endl;};
};
class der1 : public base1 {
public:
void test()
{cout<<"der1"<<endl;};
};
int main() {
der1 obj;
obj.test(); // How can I access the base class 'test()' here??
return 0;
}
You need to fully qualify the method name as it conflicts with the inherited one.
Use obj.base1::test()
You can't override a method in derived class if you didn't provide a virtual key word.
class base1
{
public:
void test()
{
cout << "base1" << endl;
};
};
class der1 : public base1
{
public:
void test()
{
cout << "der1" << endl;
};
};
int main()
{
der1 obj;
obj.test(); // How can I access the base class 'test()' here??
return 0;
}
So the above code is wrong. You have to give:
virtual void test();
in your base class
You can use this:
((base)obj).test();