C++ 使用类成员和智能指针获得多态行为

Posted

技术标签:

【中文标题】C++ 使用类成员和智能指针获得多态行为【英文标题】:C++ getting polymorphic behavior with class members and smart pointers 【发布时间】:2020-03-26 15:01:00 【问题描述】:

我有以下课程设置:

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"

我希望调用相应的 show(),但它不是很有效。我知道这是因为我正在做 A 的 make_shared 将指向 A 的 show() 而不是 B,但是如果我做 B 的 make_shared 那么我会遇到相反的问题。如何设置此类以便获得我想要的多态行为?

此外,我很确定我可以使用原始指针来实现这一点,但我确实在努力让它与智能指针一起使用。

非常感谢!

【问题讨论】:

原始指针也会有同样的问题。你需要一个虚拟克隆功能。 【参考方案1】:

你的问题是

MainClass(const A &myA) : myPolymorphicClass(std::make_shared<A>(myA)) 

在这里,您使用std::make_shared&lt;A&gt;(myA),这意味着无论myA 指的是什么,您都只会在指针中创建A 部分,这意味着您将始终调用A 版本的该功能是因为您拥有的只是A。你需要的是一个类似的模板

template <typename T>
MainClass(const T &myA) : myPolymorphicClass(std::make_shared<T>(myA)) 

现在您将创建一个指向派生类的指针,该指针将存储在myPolymorphicClass 中。如果您想甚至可以在模板中添加一些 SFINAE 以将 T 限制为从 A 派生,例如

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)) 

您可以在live example 中看到所有这些工作

【讨论】:

B b; A&amp; ref = b; MainClass m(ref); 仍然存在问题。 clone 似乎是唯一可行的解​​决方案。 太棒了,这正是我所需要的。出于几个原因,我并没有真正考虑过模板。 1) 我不知道如何将模板类型限制为 A 的子类和 2) 我不想在创建 MainClass 的实例时指定模板类型。您的答案解决了这两个问题,尽管使用 #1 的 SFINAE 和 #2 中发生的明显模板类型推导。非常感谢!

以上是关于C++ 使用类成员和智能指针获得多态行为的主要内容,如果未能解决你的问题,请参考以下文章

[C++] 智能指针的引用计数如何实现?—— 所有该类的对象共享静态类成员变量

这次肯定可以看懂C++智能指针,适合新手小白,C++内功修炼

c++动态内存管理与智能指针

C++原生指针,引用与智能指针

c++ 智能指针 shared_ptr 在多态上的使用

❥关于C++之智能指针