当前位置:   article > 正文

C++显式调用析构函数问题一二_c++显式析构

c++显式析构

问题描述

关于显示调用析构函数会不会对对象本身进行析构?
有两种结论:
(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();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

运行结果:
在这里插入图片描述
根据运行结果可以看出似乎结论2更为合理。

具体分析:

1.析构函数的作用

摘在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对象

2.调用析构函数的时机

摘在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的析构函数也被调用。

3.结论

l.~Log1();//此处显式调用了析构函数
std::cout << "l.a的值为" << l.a << std::endl;//验证显式调用析构函数,会不会destroy object
  • 1
  • 2

因此,当调用 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。

**备注:**写的比较杂,后期再整理,欢迎拍砖斧正。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/424932
推荐阅读
相关标签
  

闽ICP备14008679号