简体   繁体   中英

C++ getting polymorphic behavior with class members and smart pointers

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM