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;
}
4

5 回答 5

7

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

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

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

#include <string>

class A{
private:
   std::string name;
public:
    A(std::string n) : name(std::move(n)) {}
};

顺便说一句,这使您不必担心三法则,这意味着您不必费心编写复制构造函数、移动构造函数、复制赋值运算符、移动赋值运算符、析构函数等等。

于 2013-05-14T20:13:09.367 回答
2

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

由于您的类不拥有任何对象或内存块,因此不应删除任何内容。

于 2013-05-14T20:11:47.530 回答
1

在此示例中,您不需要删除名称。“名称”只是指向可执行映像中某个位置的指针,而不是使用 new/malloc/something_else 分配的内存。

于 2013-05-14T20:13:22.913 回答
1

“name”占用编译器自动预留的静态内存。如果您删除该内存,则行为未定义(即崩溃)。你只会“删除”你最初“新”的记忆。

于 2013-05-14T20:13:36.070 回答
1

最简单的事情是使用正确的 C++ ( std::string) 并避免裸指针,因为这样可以简化资源管理。

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

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

无需手动复制数据,无需析构函数或复制构造函数……所有这些都是开箱即用的。

于 2013-05-14T20:16:42.450 回答