我正在尝试编写非常简单的 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?
关于c++ - "heterogeneous-object"类中的复制构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12234551/