赞
踩
关于显示调用析构函数会不会对对象本身进行析构?
有两种结论:
(1)会析构对本身;
(2)不会析构对象本身,只是单纯调用析构函数;
#include <iostream> class Log1 { public: int a; Log1():a(1) { std::cout << "构造函数"; } ~Log1() { std::cout << "析构函数"; } }; void fun() { Log1 l;//调用构造函数 l.~Log1();//此处显式调用了析构函数 std::cout << "l.a的值为" << l.a << std::endl;//验证显式调用析构函数,会不会destroy object } int main() { fun();//执行完fun()函数后,会自动调用析构函数 getchar(); }
运行结果:
根据运行结果可以看出似乎结论2更为合理。
摘在Wikipedia:
Its main purpose is to free the resources (memory allocations, open files or sockets, database connections, resource locks, etc.) which were acquired by the object during its life and/or deregister from other entities which may keep references to it. Use of destructors is needed for the process of Resource Acquisition Is Initialization (RAII).
析构函数作用就是释放资源(内存分配,打开的文件,网口句柄,数据库连接等)。从定义上看析构函数并不会destroy对象。
摘在Wikipedia:
As stated above, a destructor for an object is called whenever the object’s lifetime ends.[2] If the object was created as an automatic variable, its lifetime ends and the destructor is called automatically when the object goes out of scope. Because C++ does not have garbage collection, if the object was created with a new statement (dynamically on the heap), then its destructor is called when the delete operator is applied to a pointer to the object. Usually that operation occurs within another destructor, typically the destructor of a smart pointer object.
1.对象的生命周期结束,例如对象是一个局部变量;
2.new的对象,通过delete删除对象时;
3.对象i是对象o的成员,o的析构函数被调用时,对象i的析构函数也被调用。
l.~Log1();//此处显式调用了析构函数
std::cout << "l.a的值为" << l.a << std::endl;//验证显式调用析构函数,会不会destroy object
因此,当调用 l.~Log() 函数后,还可以打印 l.a 的值,因为此处析构函数并没有destroy对象;
至于部分网友说:调用两次析构函数会导致Undefined Behavior, 其实不然:
Invoking the destructor on an object whose lifetime has ended results in undefined behavior per C++03 §12.4/6:
the behavior is undefined if the destructor is invoked for an object whose lifetime has ended
首先,这里强调的是:只有对象声明周期结束时即对象呗销毁了再次调用destructor会造成Undefined Behavior;
An object’s lifetime ends when its destructor is called per §3.8/1:
The lifetime of an object of type T ends when:
— if T is a class type with a non-trivial destructor (12.4), the destructor call starts, or
— the storage which the object occupies is reused or released.
这里解释了那些情况生命周期结束:
——含有non-trivial析构函数的类调用该析构函数
——存储对象的内存释放或是挪为他用;
Note that this means if your class has a trivial destructor, the behavior is well-defined because the lifetime of an object of such a type does not end until its storage is released, which for automatic variables does not happen until the end of the function. Of course, I don’t know why you would explicitly invoke the destructor if it is trivial.
因此,在对于那些有trivial destructorde 类的局部变量对象而言,直到局部变量所在作用域结束之前,该对象不会被销毁的。
What is a trivial destructor? §12.4/3 says:
A destructor is trivial if it is an implicitly-declared destructor and if:
— all of the direct base classes of its class have trivial destructors and
— for all of the non-static data members of its class that are of class type (or array thereof), each such class has a trivial destructor.
1.析构函数并不是销毁对象的,只是释放构造函数在构造时初始化的资源(主要包括堆上分配内存等)
2.只有类对象被销毁后再次调用用析构函数才会引起Undefined Behavior。
**备注:**写的比较杂,后期再整理,欢迎拍砖斧正。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。