好吧所以说我有一个全部定义的课程,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;
}
我的问题是:如果主方法中的两个删除语句都能正常工作,我该怎么办?
P.S。:虽然我实际上没有编译/测试过这个特定的代码,但我已经对它进行了广泛的评论(以及缩进),所以如果你发现错误,请保持良好状态。
答案 0 :(得分:2)
您正在获取文字的地址,然后在其上调用delete
,这是错误的。它未分配new
,因此您无法使用delete
解除分配(也没有任何意义)。
如果你写了new int(12)
而不是没问题,那么还有其他问题。
首先,您的班级违反了The Rule of Three。如果我复制intObject
然后同时致电delete
会怎样?你最终会在同一个指针上调用delete
两次。
其次,为什么要动态分配这些东西呢?您创建一个RAII样式包装器来为您处理释放...然后继续手动分配它。解决问题是什么问题?
我想这对你来说是一种练习,这很棒。请记住您尝试使用此代码解决的问题。
如果我使用的是std::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
分配的任何内容,但没有其他内容。永远。就是这样。
答案 1 :(得分:1)
好像你不知道你能做new int(12)
。例如,您可以将代码更改为以下内容:
Foo<int>* intObject = new Foo<int>(new int(12));
(我假设这只是为了学习,因为完全不使用new
会更好。)
另外,我刚注意到你的代码错了,也许你想要以下内容:
Foo(DT* data){ _data = data; }
virtual ~Foo(){ delete _data; }
旁注
在发布问题之前,至少尝试编译您的示例。