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