I have the following class setup:
class A {
public:
virtual void show() { // "show A" }
}
class B : A {
public:
void show() override { // "show B"}
}
class MainClass {
public:
MainClass(const A &myA) : myPolymorphicClass(std::make_shared<A>(myA)) {}
void doShow() {
myPolymorphicClass.show();
}
private:
std::shared_ptr<A> myPolymorphicClass;
}
int main {
A myA;
B myB;
MainClass myAClass(myA);
myClass.doShow(); // Will print "show A"
MainClass myBClass(myB);
myClass.doShow(); // Will also print "show A"
}
I want the corresponding show() to be called, but it's not quite working. I know it's because I'm doing make_shared of A which will point towards A's show() rather than B's, but if I do make_shared of B then I'll have the opposite problem. How can I setup this class so I get the polymorphic behavior I want?
Also I'm pretty sure I could get this working with raw pointers, but I'm really trying to get this to work with smart pointers.
Many thanks!
Your problem is with
MainClass(const A &myA) : myPolymorphicClass(std::make_shared<A>(myA)) {}
Here, you use std::make_shared<A>(myA)
which means no matter what myA
referse to, you are only going to create the A
part of it in the pointer, which means you will always call the A
version of the function because all you have is an A
. What you need is a template like
template <typename T>
MainClass(const T &myA) : myPolymorphicClass(std::make_shared<T>(myA)) {}
And now you will create a pointer to the derived class, and that will get stored in myPolymorphicClass
. If you want to can even add some SFINAE to the template to constrain T
to being derived from A
like
template <typename T, std::enable_if_t<std::is_base_of_v<A,T>, bool> = true>
MainClass(const T &myA) : myPolymorphicClass(std::make_shared<T>(myA)) {}
You can see all of this working in this live example
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.