简体   繁体   English

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

[英]C++ shared_pointer with templated classes and dynamic dispatch

I have a C++ code where I try to create a shared_pointer on a derived class. 我有一个C ++代码,尝试在派生类上创建shared_pointer When the shared_pointer is created, the dynamic dispatch stops working. 创建shared_pointer ,动态调度将停止工作。

My code: 我的代码:

#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);
}

In the copy constructor of TestClass , I first call the print() method, which works just fine. TestClass的副本构造函数中,我首先调用print()方法,该方法工作正常。 Once the shared_pointer is created, the method refers to the base class. 创建shared_pointer ,该方法将引用基类。

The output is the following: 输出如下:

Print from Child
Print from Base

Question: How can I create the shared pointer and not lose the dynamic dispatch functionality? 问题:如何创建共享指针而不丢失动态调度功能?

make_shared doesn't make an existing thing shared; make_shared不会共享现有的东西; it makes a new shared thing, with the type you give it. 它会根据您提供的类型创建一个新的共享内容。

It's effectively like this (pseudo-code only!): 实际上是这样的(仅伪代码!):

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

In this case you're creating a Base<int> , that will be shared. 在这种情况下,您将创建一个Base<int> ,它将被共享。 It is not a child of anything. 它不是什么的孩子。 It's a sliced copy of your Child<int> . 这是您的Child<int>的切片副本。

Nothing in TestClass knows that you wanted a Child<int> , or even knows that Child<int> exists as a type. TestClass任何内容都不知道您想要一个Child<int> ,甚至不知道Child<int>作为一种类型存在。

You could do shared_ptr<Base<T>> sptr = &b to obtain a shared_ptr to an existing object. 您可以执行shared_ptr<Base<T>> sptr = &b来获取现有对象的shared_ptr。 Unfortunately said object is not dynamically allocated, so that's not going to go well. 不幸的是,该对象不是动态分配的,因此执行得并不顺利。

It would really be better to be consistent with your object ownership semantics. 与对象所有权语义保持一致确实更好。 Your main function can do auto ptr = make_shared<Child<int>>() , then pass the resulting shared pointer into anything that expects a shared_ptr<Child<int>> or a shared_ptr<Base<int>> . 您的main功能可以执行auto ptr = make_shared<Child<int>>() ,然后将生成的共享指针传递给任何需要shared_ptr<Child<int>>shared_ptr<Base<int>>

Without knowing what you're actually trying to do, I cannot make any more specific suggestions. 不知道您实际上要做什么,我无法提出任何更具体的建议。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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