-
浅析:类只能有一个析构函数
2015-04-01 12:42:11类的构造函数与析构函数都是与类同名(析构函数需要加上'~'),没有返回值的;...但是由于析构函数是没有参数的,那么从而无法通过参数的不同来达到重载多个析构函数的目的,从而析构函数只能有一个。 析构函数是由系类的构造函数与析构函数都是与类同名(析构函数需要加上'~'),没有返回值的;而构造函数是可以有参数的,但是析构函数是不能有参数的。
我们知道类可以有多个构造函数,这些构造函数是重载函数的关系,也就是说函数名都是相同的,区别它们主要靠参数的不同(参数个数和参数类型)。
但是由于析构函数是没有参数的,那么从而无法通过参数的不同来达到重载多个析构函数的目的,从而析构函数只能有一个。
析构函数是由系统负责调用的,也可以手工显示调用,但是显示调用析构函数是不会析构该对象的,也就是说显示调用析构函数和没有显示调用析构函数是一样的,
#include<iostream>
using namespace std;
class A
{
public:
A(){};
void fun() {cout<<"The object exists!";};
~A(){};int bbb;
};
int main()
{
A *a=new A();a->bbb=345;
a->~A();//显示调用析构函数后,对象a还存在吗?
a->fun();
//编译运行后a->fun()能够输出,对象a仍存在
return 0;
}再来看看汇编代码
在VC的DEBUG模式下,通过查看反汇编代码,可以看到,直接调用析构函数的语句没有任何汇编代码对应它,就和没有这一语句一模一样.由此看来,析构函数是自动调用的,如果显示调用是不会析构对象的。
……
14: a->bbb = 345;
0040105B mov ecx,dword ptr [ebp-4]
0040105E mov dword ptr [ecx],159h
15: a->~A();
16: a->fun();
00401064 mov ecx,dword ptr [ebp-4]
00401067 call @ILT+15(A::fun) (00401014)
……由以上可知,一个类只能有一个析构函数,析构函数没有返回值没有参数,只能由系统调用时才析构对象。
-
C++多个类中构造函数与析构函数的调用顺序
2017-01-14 22:33:05C++中有一个很重要的法则:使用构造函数创建对象的顺序与使用析构函数释放对象的顺序相反。对于一些C++的初学者来说,这是一条有点费解的法则,那么该怎么理解和清晰的表现出来呢?下面我们通过程序来体现一下: #...在C++中有一个很重要的法则:使用构造函数创建对象的顺序与使用析构函数释放对象的顺序相反。对于一些C++的初学者来说,这是一条有点费解的法则,那么该怎么理解和清晰的表现出来呢?下面我们通过程序来体现一下:
#include<iostream> using namespace std; //创建一个汽车类 class Car { public: //构造函数 Car(short, int); //析构函数 ~Car(); void move(); private: short speed; int num; }; Car::Car(short s, int n) { speed = s; num = n; cout << "创建第" << num << "辆车,速度是" << speed << " 米/秒" << endl; } Car::~Car() { cout << "销毁掉第 " << num << "辆车" << endl; } void Car::move() { cout << "第 " << num << "辆车速度是" << speed << endl; } //主函数 void main() { //先创建第car1对象,再创建car2对象 Car car1(10, 1), car2(20, 2); car1.move(); car2.move();
}
编译执行的结果如下(编译环境为Visual Studio 2013):
分析输出结果,我们可以看到,在主函数中是首先创建了car1类,后创建了car2类,所以在执行构造函数的顺序上,是先执行car1对象的构造函数,后执行car2对象的构造函数。而在主函数执行结束,要调用析构函数的时候,根据开始说的法则,则会先执行car2类的析构函数,后执行car1类的析构函数。这就是“使用构造函数创建对象的顺序与使用析构函数释放对象的顺序相反”这条法则的一个很好的体现。
那么我们可以举一反三,如果想先执行car1类的析构函数,后执行car2类的析构函数,那么上述程序该如何修改呢?很简单,依据上述法则,我们只需要修改为先创建car2类,后创建car1类,就可以了。修改后的程序如下:
编译执行的结果如下:#include<iostream> using namespace std; class Car { public: Car(short, int); ~Car(); void move(); private: short speed; int num; }; Car::Car(short s, int n) { speed = s; num = n; cout << "创建第" << num << "辆车,速度是" << speed << " 米/秒" << endl; } Car::~Car() { cout << "销毁掉第 " << num << "辆车" << endl; } void Car::move() { cout << "第 " << num << "辆车速度是" << speed << endl; } void main() { //这次先创建car2类,后创建car1类 Car car2(20, 2), car1(10, 1); car1.move(); car2.move(); }
这次我们看到,由于是先创建了car2类,后创建了car1类,所以先执行了car2类的构造函数,后执行car1类的构造函数;而在最后,会先执行car1类的析构函数,后执行car2类的西沟函数。
当然。我们还可以再往深了想一想,上面这两个例子都是基于同一个类来创建两个对象的,那么如果是两个不同的类创建的对象呢?是否依然符合这条法则呢?我们再修改程序来验证一下:
编译执行的结果如下:#include<iostream> using namespace std; //创建一个汽车类 class Car { public: Car(short, int); ~Car(); void move(); private: short speed; int num; }; //创建一个司机类 class Driver { public: Driver(short); ~Driver(); void drive(); private: short years; }; Car::Car(short s, int n) { speed = s; num = n; cout << "创建第" << num << "辆车,速度是" << speed << " 米/秒" << endl; } Car::~Car() { cout << "销毁掉第 " << num << "辆车" << endl; } void Car::move() { cout << "第 " << num << "辆车速度是" << speed << endl; } Driver::Driver(short y) { cout << "我是一个" << y << "岁的司机" << endl; } Driver::~Driver() { cout << "我要停车了" << endl; } void Driver::drive() { cout << "我要开车了" << endl; } //主函数 void main() { //先创建汽车类 Car car1(10, 1); //后创建司机类 Driver driver1(30); driver1.drive(); car1.move(); }
通过输出结果,我们可以看到,先执行了Car1类的构造函数,后执行了Driver1类的构造函数,而在最后,则是先执行了Driver1类的析构函数,后执行了Car1类的析构函数,也就是说,不同的类依然是符合上述法则的。
上述例子较为简单,而在实际应用中,主函数中可能远比上述程序复杂的多,可能会执行更多的类操作,这样就需要我们去时刻注意一下这条法则,避免出现一些看起来很“莫名其妙”的错误。
-
C++析构函数(类的前面加上一个~)
2020-03-27 20:14:36C++析构函数析构函数介绍:示例:参考链接 析构函数是类的另一个特殊成员函数...换言之,一个类可以有多个构造函数,但是只能有一个析构函数。 析构函数介绍: 1.析构函数(destructor) 与构造函数相反,当对...
析构函数是类的另一个特殊成员函数,它的作用与构造函数相反,C++规定析构函数的名字是类的前面加上一个波浪号 (~)。
析构函数不返回任何值,没有返回类型,也没有函数参数。由于没有函数参数,因此它不能被重载。换言之,一个类可以有多个构造函数,但是只能有一个析构函数。析构函数介绍:
1.析构函数(destructor) 与构造函数相反,当对象脱离其作用域时(例如对象所在的函数已调用完毕),系统自动执行析构函数。析构函数往往用来做“清理善后” 的工作(例如在建立对象时用new开辟了一片内存空间,应在退出前在析构函数中用delete释放)。
2.以C++语言为例:析构函数名也应与类名相同,只是在函数名前面加一个位取反符,例如stud( ),以区别于构造函数。它不能带任何参数,也没有返回值(包括void类型)。只能有一个析构函数,不能重载。如果用户没有编写析构函数,编译系统会自动生成一个缺省的析构函数(即使自定义了析构函数,编译器也总是会为我们合成一个析构函数,并且如果自定义了析构函数,编译器在执行时会先调用自定义的析构函数再调用合成的析构函数),它也不进行任何操作。所以许多简单的类中没有用显示的析构函数。示例:
#include<iostream> using namespace std; class T { public: ~T(){cout<<"析构函数被调用。";} }; int main() { T *t=new T();//建立一个T类的指针对象t delete t; cin.get(); };
运行结果:
参考链接
https://blog.csdn.net/qq_15267341/article/details/78585570
https://www.cnblogs.com/liuzhenbo/p/11214276.html -
C++编程思想 第1卷 第15章 多态性和虚函数 析构函数和虚拟析构函数 纯虚析构函数
2018-08-03 23:16:27尽管纯虚析构函数在标准C++中是合法的,但在使用时有一个额外的限制:必须 为纯虚析构函数提供一个函数体 纯虚析构函数和非纯虚析构函数之间唯一的不同之处在于纯虚析构函数使得 基类是抽象类,所以不能创建一个基类...尽管纯虚析构函数在标准C++中是合法的,但在使用时有一个额外的限制:必须
为纯虚析构函数提供一个函数体纯虚析构函数和非纯虚析构函数之间唯一的不同之处在于纯虚析构函数使得
基类是抽象类,所以不能创建一个基类的对象//: C15:UnAbstract.cpp // From Thinking in C++, 2nd Edition // Available at http://www.BruceEckel.com // (c) Bruce Eckel 2000 // Copyright notice in Copyright.txt // Pure virtual destructors // seem to behave strangely class AbstractBase { public: virtual ~AbstractBase() = 0; }; AbstractBase::~AbstractBase() {} class Derived : public AbstractBase {}; // No overriding of destructor necessary? int main() { Derived d; } ///:~
一般来说,如果在派生类中基类的纯虚函数没有重新定义,则派生类将会
成为抽象类当我们的类仅含有一个纯虚函数时,就会发现这个唯一的差别:析构函数
运行下面的程序,可以看到在派生类版本之后,随着任何其他的析构函数,
调用了纯虚函数体//: C15:PureVirtualDestructors.cpp // From Thinking in C++, 2nd Edition // Available at http://www.BruceEckel.com // (c) Bruce Eckel 2000 // Copyright notice in Copyright.txt // Pure virtual destructors // require a function body #include <iostream> using namespace std; class Pet { public: virtual ~Pet() = 0; }; Pet::~Pet() { cout << "~Pet()" << endl; } class Dog : public Pet { public: ~Dog() { cout << "~Dog()" << endl; } }; int main() { Pet* p = new Dog; // Upcast delete p; // Virtual destructor call getchar(); } ///:~
作为一个准则,任何时候我们的类做都要有一个虚函数,我们应当立即增加
一个虚析构函数输出
~Dog()
~Pet() -
类的构造函数、析构函数与赋值函数
2019-09-24 07:00:01每个类只有一个析构函数和一个赋值函数,但可以有多个构造函数(包含一个拷贝 构造函数,其它的称为普通构造函数)。对于任意一个类 A,如果不想编写上述函数, C++编译器将自动为 A 产生四个缺省的函数。 ... -
c++类大四个默认函数-构造函数 析构函数 拷贝构造函数 赋值构造函数
2017-03-09 10:18:00每个类只有一个析构函数和一个赋值函数,但可以有多个构造函数(包含一个拷贝构造函数,其它的称为普通构造函数)。对于任意一个类A,如果不编写上述函数,C++编译器将自动为A 产生四个缺省的函数,例如: A(void... -
C++类的构造函数、析构函数与赋值函数
2019-01-05 22:11:33每个类只有一个析构函数和一个赋值函数,但可以有多个构造函数(包含一个拷贝构造函数,其它的称为普通构造函数)。对于任意一个类A,如果不想编写上述函数,C++编译器将自动为A产生四个缺省的函数,如 A... -
C++ 类 析构函数
2019-03-29 13:10:00一个类最多只能有一个析构函数。析构函数不返回任何值,没有函数类型,也没有函数参数,因此它不能被重载。 构造函数可能有多个,但析构函数只能有一个,就像人来到人世间,可能出生的环境家庭不同(重载构造函数)... -
类的构造函数,析构函数与赋值函数
2017-04-11 16:55:171.每个类只有一个析构函数和一个赋值函数,但是可以有多个构造函数(一个拷贝构造函数,其他为普通构造函数) 2.对于任意一个类A,如果不想编写上类函数,c++编译器会自动生成四个缺省的函数 A(void); A(const A &a);... -
C++类四个默认函数---构造函数、析构函数、拷贝函数、赋值函数
2015-04-23 11:34:27默认构造函数指不带参数或者所有参数都有缺省值的构造函数!...每个类只有一个析构函数和一个赋值函数,但可以有多个构造函数(包含一个拷贝构造函数,其它的称为普通构造函数)。对于任意一个类A,如果不编写上述 -
类的构造函数、析构函数、与赋值函数
2016-09-09 22:20:161.每个类只有一个析构函数和一个赋值函数,但可以有多个构造函数(包括一个拷贝构造函数,其它的称为普通构造函数)。对于任意一个类A,如果不想编写上述函数,C++编译器将自动为A产生四个缺省的函数,如: A(void);... -
C++:02.类的构造函数、析构函数、拷贝函数
2020-10-28 11:21:13析构函数(只能有一个)3.malloc、free、new、delete 区别4. 拷贝构造函数和调用场景 知识点: 面试题:finalize , finally, final 之间的区别 finalize : java中垃圾回收回收该对象的时候会调用的方法 (c 中的析构... -
c++ map 析构函数_C++|类继承关系中的虚函数、虚析构函数、虚基类
2020-11-24 07:04:58在继承关系中,虚函数、虚析构函数、虚基类中使用的关键字virtual都是在告诉编译器,此处要...虚基类:当派生类有多重继承和多继承时,在继承链上有两个子类继承自同一基类时,此两个子类作为基类再次派生出一个类... -
类的构造函数、析构函数、拷贝构造函数与赋值函数
2012-07-29 12:38:06每个类只有一个析构函数和一个赋值函数,但可以有多个构造函数(包含一个拷贝构造函数,其它的称为普通构造函数)。对于任意一个类A,如果不想编写上述函数,C++编译器将自动为A产生四个缺省的函数 -
C++学习之类的构造函数、析构函数
2016-03-07 22:13:00在C++的类中,都会有一个或多个构造函数、一个析构函数、一个赋值运算操作符。即使我们自己定义的类中,没有显示定义它们,编译器也会声明一个默认构造函数、一个析构函数和一个赋值运算操作符。例如: 1 //声明... -
类的构造函数与析构函数
2020-03-06 20:17:45所谓初始化,就是把一个刚创建的数据设置成我想要的值,而不是一个不能掌控的随机数。 如果初始化用的是一般的赋值,当属性很多且而大部分属性都是默认的情况下,这种方法会麻烦。 c++为类提供了初始化函数,这个... -
C++析构函数
2021-02-12 09:55:21析构函数 1.析构函数定义 2.析构函数作用 执行用户希望在最后一次使用对象之后所执行的任何操作,通常用来...一个类可以有多个构造函数,但只能有一个析构函数 用户没有定义析构函数,系统会自动生成一个析构函数 ... -
C++(1)C++类四个默认函数---构造函数、析构函数、拷贝函数、赋值函数
2016-08-24 14:43:00C++构造函数和析构函数 默认构造函数指不带参数或者所有参数都有缺省值的构造...每个类只有一个析构函数和一个赋值函数,但可以有多个构造函数(包含一个拷贝构造函数,其它的称为普通构造函数)。对于任意一个类A...
-
PowerBI重要外部工具详解
-
华中师范大学《外国文学史》历年期末试卷及参考答案.pdf
-
南京航天航空大学《数学分析》2002-2013年历年研究生入学考试试卷(含答案).pdf
-
FTP 文件传输服务
-
华东师范大学-数学分析-历年真题(1997年-2006年).pdf
-
(js)leetcode 1299. 将每个元素替换为右侧最大元素
-
辅助控制器来料检验规范模版.docx
-
南京理工大学《高等代数》08-12年历年考研试题.pdf
-
上海大学《高等代数》2000到2009历年考研真题.pdf
-
51单片机电子时钟设计.rar
-
全球变暖(连通块,bfs)
-
华中师范大学《中国古代文学史》历年期末试卷及参考答案.pdf
-
Python爬虫零基础最全入门课程
-
工程制图 AutoCAD 2012 从二维到三维
-
Spring
-
MySQL 事务和锁
-
VSCode学习【3】:VSCode汉化
-
Mycat 实现 MySQL的分库分表、读写分离、主从切换
-
华中师范大学《古代文学作品》AB卷及参考答案.pdf
-
大学生《JAVA》期末20套训练试卷(含答案,精心整理版).pdf