关于c++中的析构函数

About destructors in c++

本文关键字:析构函数 c++ 关于      更新时间:2023-10-16

问题是如何在析构函数中正确删除name ?

class A{
private:
    char *name;
public:
    A(char *n) : name(n) {}
    ~A(){
        //???
    }
}
int main(){
    A *a = new A("name");
    delete a;
    return 0;
}

如果您不更改构造函数,那么正确的方法是不删除任何内容。字符串的所有权属于客户端,因为您没有创建副本。

然而,重写它的正确方法是让构造函数用new[]分配字符串的副本,让析构函数用delete[]释放它。

真正的正确的方法是让std::string为您做所有的事情,而根本不写显式析构函数:

#include <string>
class A{
private:
   std::string name;
public:
    A(std::string n) : name(std::move(n)) {}
};

顺便说一下,这让你不必担心三法则,这意味着你不必麻烦地编写复制构造函数、移动构造函数、复制赋值操作符、移动赋值操作符、析构函数等等。

不允许删除指向字符串常量"name"的指针

由于你的类不拥有任何对象或内存块,它不应该删除任何东西

在本例中,您不需要删除name。"name"只是指向可执行映像中某个位置的指针,而不是new/malloc/something_else分配的内存

"name"占用编译器自动留出的静态内存。如果你删除内存,行为是未定义的(即崩溃)。

最简单的方法是使用适当的c++ (std::string)并避免裸指针,因为这简化了资源的管理。

你的接口的问题是类型A声明了参数的所有权,但是你不能声明字符串文字的所有权,因为它们是由实现管理的。您可以继续尝试决定调用者是否应该创建深度拷贝并将其传递给A,或者是否应该更改A设计,而不是试图声明所有权并从中复制。但事实是,如果你使用更高级的结构,事情会简单得多:

class A {
   std::string name;
public:
   A(const std::string& name) : name(name) {}
};

不需要手动复制数据,不需要析构函数或复制构造函数…