模板类内存清理问题

时间:2018-11-06 18:03:59

标签: c++

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

CDummyObject<int> obj1(123, CDummyObject<int>::eValue); //No cleanup needed
CDummyObject<int*> obj2(new int, CDummyObject<int*>::eNewPtr); //Need to call delete

但是析构函数出错,因为当使用的类型名是一个值时,它不能使用模板删除或释放代码。自从我得到了正确的保护之后,有关如何欺骗编译器以忽略错误并只是进行编译的任何提示?

类定义类似于:

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;
        }
    }
};

2 个答案:

答案 0 :(得分:1)

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

case eNewPtr:
    if (_DummyVar) delete _DummyVar;
    break;
case eNewPtrArray:
    if (_DummyVar) delete[] _DummyVar;
    break;
case eMallocPtr:
    if (_DummyVar) free(_DummyVar);
    break;

它会抱怨,因为它无法在非指针上调用delete / free

如果您的C ++版本允许if constexpr与类型特征一起使用,请考虑使用Type来确定name是否是指针。

答案 1 :(得分:1)

您可以将助手功能定义为功能模板。需要指针的重载会释放内存,对于非指针类型的重载则不执行任何操作:

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
    }