1

好吧,假设我有一门课程,其所有定义,bla bla bla ...

template <class DT>
class Foo{
private:
    DT* _data;
    //other stuff;
public:
    Foo(DT* data){ _data = data; }
    virtual ~Foo(){ delete _data; }
    //other methods
};

然后我在主要方法中有:

int main(){
    int number = 12;

    Foo<anyRandomClass>* noPrimitiveDataObject = new Foo<anyRandomClass>(new anyRandomClass());
    Foo<int>* intObject = new Foo<int>(number);

    delete noPrimitiveDataObject; //Everything goes just fine.
    delete intObject; //It messes up here, I think because primitive data types such as int are allocated in a different way.

    return 0;
}

我的问题是:我该怎么做才能让 main 方法中的两个 delete 语句都能正常工作?

PS:虽然我没有实际编译/测试过这个特定的代码,但我已经对它进行了广泛的审查(以及缩进),所以如果你发现错误,请多多关照。

4

2 回答 2

2

您正在获取文字的地址,然后delete稍后再调用它,这是错误的。它不是用 分配的new,因此你不能用它来释放它delete(也没有任何意义)。

如果你写new int(12)了,那就没问题了,但是,还有其他问题。

首先,您的班级违反了三原则。如果我复制intObject然后调用delete它们会发生什么?你最终会调用delete同一个指针两次。

其次,你为什么要动态分配这些东西?您创建一个 RAII 样式包装器来为您处理释放...然后继续手动分配它。那是解决什么问题?

我想这对你来说是一个练习,这很棒。请记住您要使用此代码解决的问题。

如果我使用 astd::vector<T>我当然不会像这样使用它:

std::vector<int> *v = new std::vector<int>;

它违背了使用向量的全部目的!现在我必须手动管理这个指针/内存,这就是创建向量类(和其他 RAII 样式类)来解决的问题。

因此,要正确使用它,请执行以下操作:

void foo() 
{
    std::vector<int> v;
    // do stuff with v
    // it allocates its memory dynamically so you don't have to.
    // when we exit the function the destructor is called, the memory 
    // deallocated, and life continues as it should.
}

使用自动存储持续时间对您有利,这就是重点。还要非常清楚谁拥有内存。如果从你的类设计中不清楚谁拥有给定的内存块,那么delete在你的析构函数中它是不安全的。


好的,您现在将代码更改为:

int number = 12;
// ...
Foo<int>* intObject = new Foo<int>(number);

同样的问题; 您正在获取分配有自动存储持续时间的变量的地址,然后调用delete它。 这是错误的。您分配的任何东西都与new您一起解除分配delete,但仅此而已。曾经。就是这样。

于 2012-10-24T22:51:25.427 回答
1

好像你不知道你能做到new int(12)。因此,例如,您可以将代码更改为以下内容:

Foo<int>* intObject = new Foo<int>(new int(12));

(我假设这只是为了学习,因为new完全不使用会更好)。

另外,我刚刚注意到您的代码是错误的,也许您想要以下内容:

Foo(DT* data){ _data = data; }
virtual ~Foo(){ delete _data; }

边注

在发布问题之前,至少尝试编译您的示例。

于 2012-10-24T22:50:56.173 回答