Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.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++ - Fatal编程技术网

C++ 模板类内存清理问题

C++ 模板类内存清理问题,c++,C++,我有一个问题,除了尝试去汇编做内存清理或通过模板参数指针和值进行子类化之外,我似乎无法想出好的解决方案。 我想这样使用我的类,如果需要,在Destructor上清理内存: CDummyObject<int> obj1(123, CDummyObject<int>::eValue); //No cleanup needed CDummyObject<int*> obj2(new int, CDummyObject<int*>::eNewPtr); /

我有一个问题,除了尝试去汇编做内存清理或通过模板参数指针和值进行子类化之外,我似乎无法想出好的解决方案。 我想这样使用我的类,如果需要,在Destructor上清理内存:

CDummyObject<int> obj1(123, CDummyObject<int>::eValue); //No cleanup needed
CDummyObject<int*> obj2(new int, CDummyObject<int*>::eNewPtr); //Need to call delete
CDummyObject对象j1(123,CDummyObject::eValue)//不需要清理
CDummyObject对象J2(新的int,CDummyObject::eNewPtr)//需要调用delete
但是在析构函数上出现错误,因为当使用的typename是一个值时,它不能使用模板包含类似delete或free的代码。有什么技巧可以让编译器忽略这些错误,并且在我已经对它们进行了适当的保护之后就直接编译它们吗

类定义类似于:

template<typename Type>
class CDummyObject
{
public:
    typedef enum
    {
        eInvalid,
        eValue,
        eNewPtr,
        eNewPtrArray,
        eMallocPtr
    } EParameterType;
private:
    Type _DummyVar;
    EParameterType _VarType;
public:
    CDummyObject(Type var, EParameterType type)
    {
        _DummyVar = var;
        _VarType = type;
    }

    ~CDummyObject()
    {
        switch (_VarType) //Free the memory if needed
        {
        case eNewPtr:
            if (_DummyVar) delete _DummyVar;
            break;
        case eNewPtrArray:
            if (_DummyVar) delete[] _DummyVar;
            break;
        case eMallocPtr:
            if (_DummyVar) free(_DummyVar);
            break;
        default:
            break;
        }
    }
};
模板
类CDummyObject
{
公众:
类型定义枚举
{
艾因瓦利德,
评价,
eNewPtr,
敌人,
eMallocPtr
}EParameterType;
私人:
DummyVar型;
EParameterType _VarType;
公众:
CDummyObject(类型变量,EParameterType类型)
{
_DummyVar=var;
_VarType=type;
}
~CDummyObject()
{
开关(_VarType)//如果需要,请释放内存
{
案例eNewPtr:
如果(_DummyVar)删除_DummyVar;
打破
案例分析:
如果(_DummyVar)删除[]_DummyVar;
打破
案例eMallocPtr:
如果(_DummyVar)为自由(_DummyVar);
打破
违约:
打破
}
}
};

不能将编译时模板类型与运行时if混合使用。如果您将
int
作为模板类型提供给类,那么编译器仍然必须能够编译以下所有内容:

case eNewPtr:
    if (_DummyVar) delete _DummyVar;
    break;
case eNewPtrArray:
    if (_DummyVar) delete[] _DummyVar;
    break;
case eMallocPtr:
    if (_DummyVar) free(_DummyVar);
    break;
它会抱怨,因为它不能在非指针上调用
delete
/
free


考虑使用<代码>如果CONTXPRPR 相反,如果C++版本允许它与类型特征一起确定是否<代码>类型< /C>是指针,则

< P>不能将编译时模板类型与运行时混合。如果您将
int
作为模板类型提供给类,那么编译器仍然必须能够编译以下所有内容:

case eNewPtr:
    if (_DummyVar) delete _DummyVar;
    break;
case eNewPtrArray:
    if (_DummyVar) delete[] _DummyVar;
    break;
case eMallocPtr:
    if (_DummyVar) free(_DummyVar);
    break;
它会抱怨,因为它不能在非指针上调用
delete
/
free


考虑使用<代码>如果CONTXPRPR 相反,如果C++版本允许它与类型特征一起确定<代码>类型< /C>是不是指针。

可以将帮助函数定义为函数模板。获取指针的重载释放内存,非指针类型的重载不起任何作用:

private:
    Type _DummyVar;
    EParameterType _VarType;

    template<class T> void deleter(T) {  /* nothing to do for non-pointer types*/ }

    template<class T> void deleter(T*) { // this overload is called for pointer types
        switch (_VarType) //Free the memory if needed
        {
        case eNewPtr:
            if (_DummyVar) delete _DummyVar;
            break;
        case eNewPtrArray:
            if (_DummyVar) delete[] _DummyVar;
            break;
        case eMallocPtr:
            if (_DummyVar) free(_DummyVar);
            break;
        default:
            break;
        }        
    }

public:
    // dtor
    ~CDummyObject() {
        deleter(_DummyVar); // while instatiating the right deleter method is selected
    }
private:
DummyVar型;
EParameterType _VarType;
模板void deleter(T){/*对于非指针类型*/}
模板void deleter(T*){//此重载是为指针类型调用的
开关(_VarType)//如果需要,请释放内存
{
案例eNewPtr:
如果(_DummyVar)删除_DummyVar;
打破
案例分析:
如果(_DummyVar)删除[]_DummyVar;
打破
案例eMallocPtr:
如果(_DummyVar)为自由(_DummyVar);
打破
违约:
打破
}        
}
公众:
//dtor
~CDummyObject(){
deleter(_DummyVar);//安装时选择了正确的deleter方法
}

您可以将助手函数定义为函数模板。获取指针的重载释放内存,非指针类型的重载不起任何作用:

private:
    Type _DummyVar;
    EParameterType _VarType;

    template<class T> void deleter(T) {  /* nothing to do for non-pointer types*/ }

    template<class T> void deleter(T*) { // this overload is called for pointer types
        switch (_VarType) //Free the memory if needed
        {
        case eNewPtr:
            if (_DummyVar) delete _DummyVar;
            break;
        case eNewPtrArray:
            if (_DummyVar) delete[] _DummyVar;
            break;
        case eMallocPtr:
            if (_DummyVar) free(_DummyVar);
            break;
        default:
            break;
        }        
    }

public:
    // dtor
    ~CDummyObject() {
        deleter(_DummyVar); // while instatiating the right deleter method is selected
    }
private:
DummyVar型;
EParameterType _VarType;
模板void deleter(T){/*对于非指针类型*/}
模板void deleter(T*){//此重载是为指针类型调用的
开关(_VarType)//如果需要,请释放内存
{
案例eNewPtr:
如果(_DummyVar)删除_DummyVar;
打破
案例分析:
如果(_DummyVar)删除[]_DummyVar;
打破
案例eMallocPtr:
如果(_DummyVar)为自由(_DummyVar);
打破
违约:
打破
}        
}
公众:
//dtor
~CDummyObject(){
deleter(_DummyVar);//安装时选择了正确的deleter方法
}

我知道原因,但所有内容都只是处理器上的一个寄存器值,不关心类型,它只是一个编译器保护。尽管如此,我认为您的建议可以解决我的问题,而无需进行重大更改,但不幸的是,我无法使用C++17。在C++17之前,您可以使用SFINAE和<代码>\u VarType可能需要成为traits类的一部分,以便可以在编译时条件中使用它。很好,我不知道SFINAE。这也行得通,但我用了另一个答案,因为我需要做的就足够了,而且更简单。对于更复杂的类模板行为,我将记住这一点。谢谢。我知道原因,但所有内容都只是处理器上的一个寄存器值,不关心类型,它只是一个编译器保护。尽管如此,我认为您的建议可以解决我的问题,而无需进行重大更改,但不幸的是,我无法使用C++17。在C++17之前,您可以使用SFINAE和<代码>\u VarType可能需要成为traits类的一部分,以便可以在编译时条件中使用它。很好,我不知道SFINAE。这也行得通,但我用了另一个答案,因为我需要做的就足够了,而且更简单。对于更复杂的类模板行为,我将记住这一点。谢谢。睡了一个好觉之后,我想到了这样的事情,而不是去组装、子类化或模板专门化,但是你的建议比我想象的更清晰/简单。感谢您以这种优雅的方式进行清理。在睡了一个好觉之后,我想到了这样的事情,而不是去组装、子类化或模板