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<A>(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& ref = b; MainClass m(ref);
仍然存在问题。 clone
似乎是唯一可行的解决方案。
太棒了,这正是我所需要的。出于几个原因,我并没有真正考虑过模板。 1) 我不知道如何将模板类型限制为 A 的子类和 2) 我不想在创建 MainClass 的实例时指定模板类型。您的答案解决了这两个问题,尽管使用 #1 的 SFINAE 和 #2 中发生的明显模板类型推导。非常感谢!以上是关于C++ 使用类成员和智能指针获得多态行为的主要内容,如果未能解决你的问题,请参考以下文章
[C++] 智能指针的引用计数如何实现?—— 所有该类的对象共享静态类成员变量