Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/154.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;基本数据类型和复杂数据类型的模板析构函数_C++_Templates - Fatal编程技术网

C++ C++;基本数据类型和复杂数据类型的模板析构函数

C++ C++;基本数据类型和复杂数据类型的模板析构函数,c++,templates,C++,Templates,在一篇文章中,我问了关于创建通用容器的问题。使用多态模板似乎是正确的选择 然而,我一辈子都不知道如何编写析构函数。我希望被分配的内存的所有者是容器,即使示例构造函数接受在某个其他点分配的T数组(及其维度) 我希望能够做一些像 MyContainer<float> blah(); ... delete blah; MyContainer blah(); ... 删除废话; 及 MyContainer complexBlah(); ... 删除complexBlah` 我可以这样做

在一篇文章中,我问了关于创建通用容器的问题。使用多态模板似乎是正确的选择

然而,我一辈子都不知道如何编写析构函数。我希望被分配的内存的所有者是容器,即使示例构造函数接受在某个其他点分配的
T
数组(及其维度)

我希望能够做一些像

MyContainer<float> blah();
...
delete blah;
MyContainer blah();
...
删除废话;

MyContainer complexBlah();
...
删除complexBlah`
我可以这样做吗?没有智能指针我能做到吗


再次感谢您的投入。

这是可以做到的,但这是非常先进的东西。
您需要使用类似于boostmpl库()的东西,以便让MyContainer的析构函数选择对容器上的单个项目执行的正确析构函数。您可以使用boosttypetraits库来决定需要哪种类型的删除()。我相信它会有一个特性,让您决定所包含的类型是否是指针,从而决定如何销毁它。您可能需要自己实现traits,以便在MyContainer中使用具有任何其他特定删除要求的任何其他类型。祝你好运!如果您解决了它,请向我们展示您是如何做到的。

如果您想存储指向复杂类型的指针,我建议您将容器用作:
MyContainer
,对于基本类型,只需使用
MyContainer

shared_ptr
应该注意在复杂类型被销毁时适当地删除它。并且当原语类型被破坏时,不会发生任何幻想



如果以这种方式使用容器,则不需要太多析构函数。您如何在集装箱中存放您的物品?您使用STL容器还是堆上的数组?STL容器将负责删除自身。如果删除数组,这将导致执行每个元素的析构函数,如果每个元素都是
共享的\u ptr
,则
共享的\u ptr
析构函数将删除它自己持有的指针。

如果不想使用智能指针,可以尝试部分模板专门化,它让您可以编写一个模板,该模板仅在使用指针类型安装容器时使用。

您很可能希望在此处使用智能指针,它确实简化了问题。然而,作为练习,很容易确定给定类型是否为指针。粗略的实现(可能更优雅,但我不想介绍int2type):

typedef char-YesType;
typedef char NoType[2];
模板
结构指示器
{
typedef NoType结果;
};
模板
结构指示器
{
typedef-YesType结果;
};
模板
结构MyContainer
{
~MyContainer()
{
IsPointer::结果r;
清除(&r);
删除[]数据;
}
空白清除(YesType*)
{
对于(int i=0;i

})

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


虽然向您展示了一种使用模板专门化删除包含的对象(如果它们是指针,而不是指针)的方法,但这似乎是一个脆弱的解决方案。如果您想要这样的行为,最好使用提供这种确切行为的库。标准库没有这样做的原因是,容器本身不知道它们是否控制所包含的指针-您需要将指针封装在一个知道的类型中-即智能指针。

我在堆上做了一个数组,但我可能会转到STL向量。一个相关的问题是“STL是如何做到的?”。STL容器将在其自身被销毁时销毁它们所包含的元素。STL容器不会拥有指针的所有权。谁知道指针指向什么,它不一定需要删除。例如,如果你在内存中有一张图片,你可能会在其中存储pallete信息,并且有一个指针指向它。这不属于指针,不应被删除。所以,当指针指向分配的内存时,您必须自己删除它们。shared_ptr则不同,它们用于它们所管理的对象需要某种清理的地方(通常,但不总是通过执行删除)。在注释中找到答案很难,如果还没有,你应该创建一个新问题!另外,“MyContainer blah();”定义了一个函数原型,而不是一个变量。要声明变量,删除括号。C++——不可判定的选择语言:/答案几乎是完美的。它可以正确地删除指针和基本数据类型。然而,我似乎不能使它没有错误。valgrind错误相当迟钝,但我会继续使用它,看看是否能弄清楚到底发生了什么。
MyContainer<ComplexObjectType*> complexBlah();
...
delete complexBlah;`
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;