1

我有一个模板化的包装器,其中包含一个继承纯虚拟类的类的实例。
我的问题是如何将数据存储在包装器中。
- 我不能使用副本,因为无法实例化纯虚拟类(如果我使用简单的虚拟类,则无法切片)。
- 我没有设法保留参考。这个 ref 变得无效,因为我不管理我得到的对象的分配(超出范围)。
- 我唯一的解决方案是使用指针,即使我想避免这种情况,因为那不是很安全,我需要我的代码是健壮的。
我能做些什么?

这是一个模拟我的问题的小例子:

#include <iostream>
#include <string>
#include <ctime>
#include <cmath>

using namespace std;

class Module
{
public:
    Module() : m(rand())
    {
        cout << "m = " << m << endl;
    }

    virtual void f() = 0;

    int m;
};

class ModuleA : public Module
{
public:
    ModuleA() : ma(rand())
    {
        cout << "ma = " << ma << endl;
    }

    void f() {}

    int ma;
};

template<typename T>
class Container
{
public:
    Container(T e) : element(e) {}

    T element;
};

// Objects are created outside of main
ModuleA createModule()
{
    return ModuleA();
}

Container<Module&> createContainer()
{
    return Container<Module&>(createModule());
}

int main()
{
    srand((unsigned int)time(NULL));

    Container<Module&> conta = createContainer();

    ModuleA& ca1 = dynamic_cast<ModuleA&>(conta.element); // wrong !

    system("pause");

    return 0;
}
4

1 回答 1

2

您可以std::shared_ptr在容器中使用 a ,即

template<typename T>
class Container
{
public:
    // The pointer you get must be managed as well
    Container(std::shared_ptr<T> e) : element(e) {}

    std::shared_ptr<T> element;
};

那将是完全安全的。事实上,如果对象在创建它的代码中超出范围,您仍然有一个有效的指针,直到容器自身超出范围。您可以进一步调整内存所有权关系,std::weak_ptr或者std::unique_ptr如果语义std::shared_ptr不完全适合您的情况。

您绝对应该查看std::weak_ptr,因为它允许您禁止某些代码获取指针的所有权,但如果指针在您需要访问它的位置有效,则仍然允许访问。它还可以防止内存保留周期,因为 anstd::weak_ptr不拥有内存。

于 2015-03-19T11:30:24.527 回答