c++ - "heterogeneous-object"类中的复制构造函数

标签 c++ templates

我正在尝试编写非常简单的 Any 对象,它可以保存任何类型的对象。我希望它在容器内部使用,实现异构容器。

#include <iostream>
#include <vector>
#include <string>

struct Any
{
    template < typename T >
    Any(const T & t) 
        :p(new storageImpl<T>(t)) { }

    ~Any() 
    {
        delete p;
    }

    struct storage
    {
        virtual ~storage() {}
    };

    template <typename T>
    struct storageImpl : storage
    {
        storageImpl(const T & t) : data(t) {}
        T data;
    };

    template <typename T>
    T & get()
    {
        storageImpl<T> * i = static_cast<storageImpl<T>*>(p);
        return i->data;
    }

    storage * p;
};

使用

int main ()
{
    //block1
    Any copy(Any(std::string("foo")));      
    std::cout << copy.get<std::string>();   

    //block2
    std::vector<Any> cont;
    cont.push_back(Any(5));
    cont.push_back(Any(37.9f));
    std::cout << cont[0].get<int>();    
    std::cout << cont[1].get<float>();  
}

我在复制构造方面遇到问题。

当我将 Any 插入 vector (//block2)时,未命名的 Any 被销毁,因此指针被删除,并且插入的对象不再有效。

所以我有两个问题:

1、如何为Any类编写复制构造函数?

2、为什么block1中未命名的Any没有被销毁,所以它的指针没有被删除?\

编辑 我已经尝试过了

template <typename T>
Any(const Any & rhs)
    :p(new storageImpl<T>(rhs.get()))
{
}

但它没有被触发。

最佳答案

Any不是模板类。尝试将复制构造函数模板化为 template <typename T> Any(const Any & rhs)毫无意义。

您可以做的是使用 virtual constructor成语,让storageImpl复制自身。这也是Boost.Any中使用的方法。

struct Any {
    template < typename T >
    Any(const T& t) : p(new storageImpl<T>(t)) {}

    Any(const Any& other) : p(other.p->clone()) {}
 // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    ~Any() { delete p; }

    struct storage {
        virtual ~storage() {}
        virtual storage* clone() = 0;
     // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    };

    template <typename T>
    struct storageImpl : storage {
        storageImpl(const T & t) : data(t) {}

        virtual storage* clone() { return new storageImpl(data); }
     // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

        T data;
    };

    template <typename T>
    T& get() {
        storageImpl<T>* i = static_cast<storageImpl<T>*>(p);
        return i->data;
    }

    storage * p;
};

请注意,这个实现有很多问题,例如get()方法不会检查 Any 是否真的持有 T。最好使用经过良好测试的库,例如Boost.Any .


Why isn't unnamed Any in block1 destroyed, so its pointer isn't deleted?

Copy elision .

关于c++ - "heterogeneous-object"类中的复制构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12234551/

相关文章:

c++ - 如何在 Xcode 9.3 中显示 C++ 代码文档?

c# - 使用 Visual Studio 内置的 ASP.NET MVC 模板

java - 此代码出现运行时错误与编译错误的原因

c++ - 类崩溃编译器中的 MSVC 2010 模板化映射

c++ - 来自不同类型的模板类复制构造函数 : should it follow the Rule of Five?

尝试呈现 SDL_Texture : Invalid texture 时出现 C++ SDL2 错误

c++ - 缺少类模板 "Complex"的参数列表

C++“不匹配运算符=”lambda函数中的错误

c++ - SFML 像素操作 - 更改窗口中单个字符的大小

c++ - 为什么在部分特化中不能推导从属模板类型?