C++ shared_pointer 具有模板化 类 和动态调度

C++ shared_pointer with templated classes and dynamic dispatch

我有一个 C++ 代码,我尝试在派生的 class 上创建 shared_pointer。创建 shared_pointer 后,动态调度停止工作。

我的代码:

#include <iostream>
#include <memory>

using namespace std;

template <typename T>
class Base
{
public:
    virtual void print()
    {
        cout << "Print from Base" << endl;
    }

};

template <typename T>
class Child : public Base<T>
{
public:
    virtual void print()
    {
        cout << "Print from Child" << endl;
    }
};

template <typename T>
class TestClass: public Base<T>
{
public:
    TestClass<T> (Base<T> &b)
    {
        b.print();
        shared_ptr<Base<T>> sptr = make_shared<Base<T>> (b);
        sptr->print();
    }
};

int main()
{
    Child<int> child;
    TestClass<int> cl(child);
}

TestClass的拷贝构造函数中,我先调用了print()方法,效果很好。创建 shared_pointer 后,该方法将引用基础 class。

输出如下:

Print from Child
Print from Base

问:如何创建共享指针而不丢失动态调度功能?

make_shared 不会共享现有的东西;它创建了一个新的共享对象,你给它的类型。

实际上是这样的(仅限pseudo-code!):

template <typename T>
shared_ptr<T> make_shared(Args...)
{
    shared_ptr<T> newPtr = new T(args...);
    return newPtr;
}

在这种情况下,您正在创建一个 Base<int>,它将被共享。它不是任何东西的child。这是你的 Child<int>.

的切片副本

TestClass 中没有人知道您想要 Child<int>,甚至不知道 Child<int> 作为类型存在。

您可以执行 shared_ptr<Base<T>> sptr = &b 以获得现有 object 的 shared_ptr。不幸的是 object 不是动态分配的,所以不会很顺利。

与您的 object 所有权语义保持一致真的会更好。您的 main 函数可以执行 auto ptr = make_shared<Child<int>>(),然后将生成的共享指针传递给任何需要 shared_ptr<Child<int>>shared_ptr<Base<int>>.

的对象

在不知道您实际尝试做什么的情况下,我无法提出任何更具体的建议。