问题是如何在 A 析构函数中正确删除 name ?
class A{
private:
char *name;
public:
A(char *n) : name(n) {}
~A(){
//???
}
}
int main(){
A *a = new A("name");
delete a;
return 0;
}
答案 0 :(得分:7)
鉴于您没有更改构造函数,那么正确的方法是不删除任何内容。字符串的所有权属于客户端,因为您没有创建副本。
但是,正确的重写方法是让构造函数使用new[]
分配字符串的副本,并让析构函数使用delete[]
解除分配。
和 真正正确的方法是让std::string
为你做整件事,而不是写一个明确的析构函数:
#include <string>
class A{
private:
std::string name;
public:
A(std::string n) : name(std::move(n)) {}
};
顺便说一句,这使您不必担心规则三,这意味着您不必费心编写复制构造函数,移动构造函数,复制赋值运算符,移动赋值运算符,析构函数还有什么。
答案 1 :(得分:2)
不允许删除指向字符串常量"name"
的指针。
由于您的类不拥有任何对象或内存块,因此不应删除任何内容。
答案 2 :(得分:1)
在此示例中,您无需删除名称。 “name”只是指向可执行映像中某些位置的指针,而不是使用new / malloc / something_else分配的内存。
答案 3 :(得分:1)
“name”占用编译器自动留出的静态内存。如果删除该内存,则行为未定义(即崩溃)。你只是首先“删除”你'新'的记忆。
答案 4 :(得分:1)
最简单的方法是使用正确的C ++(std::string
)并避免使用裸指针,因为这样可以简化资源管理。
您的界面存在的问题是类型A
声明了参数的所有权,但您不能声明字符串文字的所有权,因为这些是由实现管理的。您可以继续尝试确定调用者是否应创建深层副本并将其传递给A
,或者如果A
设计应更改为不尝试声明所有权并从中复制出来。但事实是,如果你只是使用更高级别的结构,事情就会简单得多:
class A {
std::string name;
public:
A(const std::string& name) : name(name) {}
};
无需手动复制数据,不需要析构函数或复制构造函数......所有工作都是开箱即用的。