Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

析构函数是可以显式调用的 #7

Open
tnie opened this issue Apr 3, 2018 · 4 comments
Open

析构函数是可以显式调用的 #7

tnie opened this issue Apr 3, 2018 · 4 comments
Labels
good first issue Good for newcomers

Comments

@tnie
Copy link
Owner

tnie commented Apr 3, 2018

内存的分配和释放是由编译器运行时在栈上自动操作的(new/delete 对应的堆操作除外),虽然就像 new/delete,内存分配和对象构造组合在一起,对象析构和内存释放组合在一起,但“组合”也就意味着两者是独立的概念:构造函数不负责内存分配,析构函数也不负责内存释放。

当只传入一个指针类型的实参时,定位 new 表达式构造对象但是不分配内存。引用自第 729 页。

调用析构函数可以清除给定的对象但是不会释放该对象所在的空间。如果需要的话,我们可以重新使用该空间。引用自第 730 页

@tnie
Copy link
Owner Author

tnie commented Apr 3, 2018

其实给我带来惊讶的是跳出自己思维盲区的一个操作:竟然还可以显式地调用析构函数。

显式调用构造函数也是可以的。

https://blog.csdn.net/jnu_simba/article/details/8803377

@tnie tnie added the good first issue Good for newcomers label Apr 3, 2018
@tnie
Copy link
Owner Author

tnie commented Apr 3, 2018

以下描述貌似和上文相悖:

析构函数一般用来释放对象所分配的资源。例如,string 构造函数(以及其他 string 成员)会分配内存来保存构成 string 的字符。string 析构函数就负责释放这些内存。类似的,vector 的若干操作都会分配内存来保存其元素。vector 析构函数就负责销毁这些元素,并`释放它们所占用的内存。 引用自《C++ Primer》第 402 页

string vector 是容器,它们的构造、析构中是妥妥的动态分配内存、释放内存的。

@tnie
Copy link
Owner Author

tnie commented Apr 3, 2018

“显式调用析构函数并不释放内存” 标题给人误解:不显式调用析构函数就会释放内存似的。实际上正如前文描述,析构只负责销毁对象(有时会包含「释放动态申请的内存」任务),虽然和内存释放组合在一起,但释放内存并不是由析构函数带来的。

@tnie tnie changed the title 显式调用析构函数并不释放内存 析构函数是可以显式调用的 Apr 3, 2018
@tnie
Copy link
Owner Author

tnie commented Apr 3, 2018

显式析构带来的直接影响就是二次析构,具体是否会带来不良影响需要看具体的业务逻辑。

void test()
{
    auto ptr = new Person(1);
    ptr->~Person();
    ptr->echo();
    delete ptr;
}

void test2()
{
    Person ins(33);
    ins.echo();
    ins.~Person();
    //ins.echo();
}

最可能的负面影响就是当析构中释放动态内存时,如果未作判断直接释放就会抛出堆异常。

Person::~Person()
{
    cout << "~Person" << endl;
    //if (p)
    {
        delete p;
        //p = nullptr;
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

1 participant