C ++ shared_pointer с шаблонными классами и динамической диспетчеризацией - PullRequest
0 голосов
/ 17 февраля 2019

У меня есть код 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

Вопрос: Как создать общий указатель и не потерять функциональность динамической отправки?

1 Ответ

0 голосов
/ 17 февраля 2019

make_shared не делится существующей вещью;он создает новую совместно используемую вещь, с типом, который вы ей даете.

Это эффективно так (только псевдокод!):

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

В этом случае вы создаете Base<int>, это будет общим.Это не ребенок ничего.Это нарезанная копия вашего Child<int>.

Ничто в TestClass не знает, что вы хотели Child<int>, или даже знает, что Child<int> существует как тип.

Вы можетевыполните shared_ptr<Base<T>> sptr = &b, чтобы получить shared_ptr для существующего объекта.К сожалению, указанный объект не выделяется динамически, поэтому он не будет работать хорошо.

Было бы действительно лучше соответствовать семантике владения вашим объектом.Ваша main функция может выполнить auto ptr = make_shared<Child<int>>(), а затем передать полученный общий указатель на все, что ожидает shared_ptr<Child<int>> или shared_ptr<Base<int>>.

Не зная, что вы на самом деле пытаетесь сделать, я не могувносите более конкретные предложения.

...