简体   繁体   English

关于C ++中的析构函数

[英]About destructors in c++

The question is how to correctly delete name in A destructor? 问题是如何正确删除A析构函数中的名称

class A{
private:
    char *name;
public:
    A(char *n) : name(n) {}
    ~A(){
        //???
    }
}

int main(){
    A *a = new A("name");
    delete a;
    return 0;
}

Given that you do not change the constructor, then the correct way is to not delete anything. 鉴于您不更改构造函数,因此正确的方法是不删除任何内容。 Ownership of the string belongs to the client, since you are not creating a copy. 字符串的所有权属于客户端,因为您没有创建副本。

However, the right way of rewriting this is to let the constructor allocate a copy of the string with new[] and let the destructor deallocate it with delete[] . 但是,重写此方法的正确方法是让构造函数使用new[]分配字符串的副本,并让析构函数使用delete[]对其进行取消分配。

And the really right way is to let std::string do the whole thing for you, and not write an explicit destructor at all: 真正正确的方法是让std::string做整个事情给你,而不是写一个明确的析构函数都:

#include <string>

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

This, by the way, allows you not to worry about the Rule of Three, which means you won't have to bother writing a copy constructor, a move constructor, a copy assignment operator, a move assignment operator, a destructor and whatnot. 顺便说一下,这使您不必担心“三定律”,这意味着您不必费心编写副本构造函数,移动构造函数,副本赋值运算符,移动赋值运算符,析构函数等等。

You are not allowed to delete a pointer to string constant "name" . 不允许删除指向字符串常量"name"的指针。

As your class does not own any objects or memory blocks, it should not delete anything. 由于您的类不拥有任何对象或内存块,因此不应删除任何内容。

In this example you don't need to delete name. 在此示例中,您不需要删除名称。 "name" is just a pointer to some some place in executable image, not memory allocated with new/malloc/something_else. “名称”只是指向可执行映像中某个位置的指针,而不是用new / malloc / something_else分配的内存。

"name" occupies static memory that the compiler automatically sets aside. “名称”占用编译器自动保留的静态内存。 If you delete that memory, the behavior is undefined (ie crash). 如果删除该内存,则行为是不确定的(即崩溃)。 You only 'delete' memory that you 'new' in the first place. 首先,您仅“删除”您“新”的内存。

The simplest thing is to use proper C++ ( std::string ) and avoid naked pointers, as that simplifies management of resources. 最简单的方法是使用适当的C ++( std::string )并避免使用裸露的指针,因为这样可以简化资源管理。

The problem with your interface is that the type A claims ownership of the argument, but you cannot claim ownership of a string literal, as those are managed by the implementation. 接口的问题是类型A声明了参数的所有权,但是您不能声明字符串文字的所有权,因为字符串文字是由实现管理的。 You could go on trying to decide whether the caller should create deep copy and pass it to a A or if A design should be changed not to attempt to claim ownership and make a copy out of that. 您可以继续尝试确定调用方是否应该创建深层副本并将其传递给A或者是否应该更改A设计以不尝试声明所有权并从中复制副本。 But the fact is that things are much simpler if you just use higher level constructs: 但是事实是,如果您只使用更高级别的结构,事情就会简单得多:

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

No need to manually copy data around, no need for a destructor or a copy constructor... all works out of the box. 无需手动复制数据,不需要析构函数或复制构造函数...所有这些都可以直接使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM