我有一个班级constructor
将对象的地址作为参数。
MyClass(OtherClass * otherClass);
在本课程的Destructor
中,我尝试delete
OtherClass
的实例。
~MyClass() {
if(otherClass != nullptr) {
delete otherClass;
}
}
我遇到的问题是,当我调用此constructor
时,我使用stack
中的元素而不是heap
来调用它,因此我将其称为如下:< / p>
MyClass myClass(&amp; otherObject);
所以当myClass
对象超出范围时,我得到一个例外。如果我在OtherObject
或stack
上声明了heap
变量,我该如何表达?或者换句话说,我怎么知道我是否可以delete
该对象?
答案 0 :(得分:6)
虽然有一些特定于系统的方法可能会判断内存是来自堆还是来自堆栈,但这实际上并没有真正帮助:你可能有一个指向另一个对象成员的指针。堆。内存将在堆上,但您仍然不负责删除该对象。换句话说: not 沿着您所在的道路前进!
处理问题的正确方法是在界面中明确地清楚所有权语义,然后继续使用。您可以采取两种方向:
std::unique_ptr<OtherClass>
管理它们。delete
所有对象都将负责。调用者负责不将指针传递给其他地方管理的对象,例如,堆栈或成员对象上的对象。有一种混合方法,你的班级有时会对物品负责,但并非总是如此。但是,这种方法的实现实际上是上述两种方法的组合:您将合适的智能指针作为构造函数参数,并确保智能指针构造是用户的责任适合您班级的用户。例如,您的类可以使用std::shared_ptr<OtherClass>
,其正常构造将delete
对象。当用户想要传入指向另外拥有的对象的指针时,std::shared_ptr<OtherClass>
将使用删除器来构造,该删除器不 delete
指针。这是一个简单的程序,演示std::shared_ptr
的两种不同管理策略:
#include <iostream>
#include <memory>
struct foo {
char const* name;
foo(char const* name)
: name(name) {
std::cout << "foo::foo(" << name << "): " << this << "\n";
}
~foo() {
std::cout << "foo::~foo(" << name << "): " << this << "\n";
}
};
int main() {
std::shared_ptr<foo>(new foo("heap"));
foo f("stack");
std::shared_ptr<foo>(&f, [](auto){});
}