Arc*_*ede 2 c++ memory-management
我有一个类,constructor它将对象的地址作为参数.
MyClass(OtherClass * otherClass);
Run Code Online (Sandbox Code Playgroud)
在Destructor这个类中,我尝试delete了实例OtherClass.
~MyClass() {
if(otherClass != nullptr) {
delete otherClass;
}
}
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是,当我调用constructor它时,我用一个元素来stack代替heap它来调用它,因此我将其称为如下:
MyClass myClass(&otherObject);
所以当myClass对象超出范围时,我得到一个例外.如果我的OtherObject变量是stack在heap?或者?上声明的,我怎么能够喜欢?或者换句话说,我怎么知道我是否可以delete对象?
虽然有一些系统特定的方法可能能够判断内存是来自堆还是来自堆栈,但这实际上并没有真正帮助:你可能有一个指向堆上另一个对象成员的指针.内存将在堆上,但您仍然不负责删除该对象.换句话说:不要不下去你的路径!
处理问题的正确方法是在界面中明确地清楚所有权语义,然后继续使用.您可以采取以下两个方向:
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){});
}
Run Code Online (Sandbox Code Playgroud)