关于c ++中的析构函数

时间:2013-05-14 20:10:22

标签: c++ destructor

问题是如何在 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;
}

5 个答案:

答案 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) {}
};

无需手动复制数据,不需要析构函数或复制构造函数......所有工作都是开箱即用的。