因为它有一个非动态分配的 int 的地址,所以我
我以为我不需要删除它。
没错。干脆不要删除它。
您问题的第二部分是关于动态分配的内存。在这里,您必须多考虑并做出一些决定。
假设您的名为 ex1 的类在其构造函数中接收到一个原始指针,用于在类外部动态分配的内存。
作为类的设计者,你必须决定这个构造函数是否“取得这个指针的所有权”。如果是,则 ex1 负责删除其内存,您可能应该在类析构函数上执行此操作:
class ex1 {
public:
/**
* Warning: This constructor takes the ownership of p_intvar1,
* which means you must not delete it somewhere else.
*/
ex1(int* p_intvar1)
{
ptoint = p_intvar1;
}
~ex1()
{
delete ptoint;
}
int* ptoint;
};
但是,这通常是一个糟糕的设计决定。您必须为此类的用户 root 阅读构造函数的注释,并记住不要删除在类 ex1 之外的某处分配的内存。
接收指针并取得其所有权的方法(或构造函数)称为“sink”。
有人会像这样使用这个类:
int* myInteger = new int(1);
ex1 obj(myInteger); // sink: obj takes the ownership of myInteger
// never delete myInteger outside ex1
另一种方法是说您的类 ex1 不获取所有权,并且为该指针分配内存的人负责删除它。 ex1 类不能删除其析构函数上的任何内容,应该这样使用:
int* myInteger = new int(1);
ex1 obj(myInteger);
// use obj here
delete myInteger; // remeber to delete myInteger
同样,您班级的用户必须阅读一些文档才能知道他负责删除这些内容。
如果您不使用现代 C++,则必须在这两个设计决策之间做出选择。
在现代 C++(C++ 11 和 14)中,您可以在代码中明确说明(即不必仅依赖代码文档)。
首先,在现代 C++ 中,您避免使用原始指针。您必须在两种“智能指针”之间进行选择:unique_ptr 或 shared_ptr。它们之间的区别在于所有权。
正如他们的名字所说,一个唯一指针只属于一个人,而共享指针可以由一个或多个人拥有(所有权是共享的)。
唯一指针 (std::unique_ptr) 不能被复制,只能从一个地方“移动”到另一个地方。如果一个类有一个唯一的指针作为属性,那么这个类就明确地拥有那个指针的所有权。如果一个方法接收到一个唯一的指针作为副本,那么它就明确表示它是一个“接收器”方法(获取指针的所有权)。
你的类 ex1 可以这样写:
class ex1 {
public:
ex1(std::unique_ptr<int> p_intvar1)
{
ptoint = std::move(p_intvar1);
}
std::unique_ptr<int> ptoint;
};
这个类的用户应该像这样使用它:
auto myInteger = std::make_unique<int>(1);
ex1 obj(std::move(myInteger)); // sink
// here, myInteger is nullptr (it was moved to ex1 constructor)
如果您忘记在上面的代码中执行“std::move”,编译器将生成一个错误,告诉您 unique_ptr 不可复制。
还请注意,您永远不必明确删除内存。智能指针会为您处理。