【问题标题】:C++ shared_pointer with templated classes and dynamic dispatch具有模板类和动态调度的 C++ shared_pointer
【发布时间】:2019-02-17 19:28:08
【问题描述】:

我有一个 C++ 代码,我尝试在派生类上创建 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 后,该方法将引用基类。

输出如下:

Print from Child
Print from Base

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

【问题讨论】:

  • 这是因为你正在构造一个新的基类,而不是一个带有复制构造函数的新子类。
  • 听起来好像这个人在找shared_from_this?

标签: c++ inheritance polymorphism shared-ptr


【解决方案1】:

make_shared 不会共享现有事物;它使用您指定的类型创建了一个新的共享事物。

实际上是这样的(仅限伪代码!):

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

在这种情况下,您将创建一个Base&lt;int&gt;,它将被共享。它不是任何事物的孩子。这是您的Child&lt;int&gt; 的切片副本。

TestClass 中的任何内容都不知道您想要 Child&lt;int&gt;,甚至不知道 Child&lt;int&gt; 作为一种类型存在。

您可以执行shared_ptr&lt;Base&lt;T&gt;&gt; sptr = &amp;b 来获取现有对象的shared_ptr。不幸的是,所说的对象不是动态分配的,所以不会很顺利。

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

在不知道你真正想要做什么的情况下,我无法提出更具体的建议。

【讨论】:

  • 您可以为 shared_ptr 使用自定义析构函数,当 ref 计数为 0 时不会导致任何问题,但这完全没有意义,并且会导致大量开销和性能损失以实现零增益.
  • 是的,就是这样
猜你喜欢
  • 2019-04-18
  • 1970-01-01
  • 2013-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多