原始和复杂数据类型的C ++模板析构函数

时间:2008-10-04 00:15:38

标签: c++ templates

related question中,我询问了如何创建通用容器。使用多态模板似乎是正确的方法。

但是,我不能为我的生活弄清楚应该如何编写析构函数。我希望分配的内存的所有者是容器,即使示例构造函数接收了T的数组(及其维度),也在其他位置分配。

我希望能够做类似

的事情
MyContainer<float> blah();
...
delete blah;

MyContainer<ComplexObjectType*> complexBlah();
...
delete complexBlah;`

我可以这样做吗?我可以在没有智能指针的情况下完成吗?

再次感谢您的意见。

5 个答案:

答案 0 :(得分:4)

我建议您是否要存储指向复杂类型的指针,将容器用作MyContainer<shared_ptr<SomeComplexType> >,对于基本类型,只需使用MyContainer<float>

shared_ptr应该在被破坏时适当地删除复杂类型。当原始类型被破坏时,什么都不会发生。


如果以这种方式使用容器,则不需要太多的析构函数。你如何把你的物品放在容器里?您是否在堆上使用STL容器或数组? STL容器会自行删除。如果删除数组,这将导致每个元素的析构函数被执行,如果每个元素都是shared_ptrshared_ptr析构函数将删除它自己持有的指针。

答案 1 :(得分:1)

你很可能想在这里使用智能指针,它确实简化了问题。但是,就像一个练习一样,确定给定类型是否为指针很容易。粗略的实现(可能更优雅,但我不想介绍int2type):

typedef char YesType;
typedef char NoType[2];

template<typename T>
struct IsPointer
{
typedef NoType  Result;
};
template<typename T>
struct IsPointer<T*>
{
typedef YesType Result;
};

template<typename T>
struct MyContainer
{
~MyContainer()
{
    IsPointer<T>::Result r;
    Clear(&r);
    delete[] data;
}
void Clear(YesType*)
{
    for (int i = 0; i < numElements; ++i)
        delete data[i];
}
void Clear(NoType*) {}

T*  data;
int numElements;

};

答案 2 :(得分:0)

可以做到,但这是非常先进的东西。 你需要使用类似boost MPL库(http://www.boost.org/doc/libs/1_36_0/libs/mpl/doc/index.html)的东西,这样你就可以让MyContainer的析构函数选择正确的破坏形式,它需要对容器上的各个项目进行破坏。您可以使用boost TypeTraits库来决定需要哪种删除(http://www.boost.org/doc/libs/1_36_0/libs/type_traits/doc/html/index.html)。我确信它会有一个特性让你决定你所包含的类型是否是一个指针,从而决定它是如何被破坏的。您可能需要自己为要在MyContainer中使用的具有任何其他特定删除要求的任何其他类型实现特征。祝你好运!如果你解决了,请告诉我们你是如何做到的。

答案 3 :(得分:0)

如果您不想使用智能指针,可以尝试部分模板特化,那么您可以编写一个模板,仅在使用指针类型实例化容器时使用。

答案 4 :(得分:0)

delete用于释放先前使用new分配的内存。你不需要在这里使用delete,当blah和complexBlah超出范围时,它们将自动被销毁。

虽然yrp's answer向您展示了一种使用模板特化来删除包含的对象的方法,如果它们不是指针,那么这似乎是一个脆弱的解决方案。如果你想要这样的行为,你最好使用Boost Pointer Container库来提供这种确切的行为。标准库不是因为容器本身不知道它们是否控制包含的指针 - 你需要将指针包装成一个知道的类型 - 即智能指针。