c++基础语法:构造函数与析构函数_C 语言

说实话c++还是以前在学校的时候用过的,从毕业到现在一直用c嵌入式编程,现在重新搬出C++语法 ,如果理解上有错误的地方,还请路过的朋友多指正~~~

构造函数用来构造一个对象,主要完成一些初始化工作,如果类中不提供构造函数,编译器会默认的提供一个默认构造函数(参数为空的构造函数就是默认构造函数) ;析构函数是隐式调用的,delete对象时候会自动调用完成对象的清理工作。

现在主要看看继承中的构造函数和析构函数的调用:

复制代码 代码如下:

class  A {} ;
class  B : public A
{};
class  C : public B
{};

c * ptr = new C() ;
delete ptr ;

一般来说,上面的代码构造函数是先调用最根父类的构造函数,然后是次一级父类构造函数,依次而来直到派生类本身的构造函数,而且对父类构造函数的调用都是父类的默认构造函数(当然也可以显示地调用父类的非默认构造函数),也就是说派生类在构造本身之前会首先把继承来的父类成分先构造好;

对析构函数的调用是先调用派生类本身的析构函数,然后是上一层父类析构函数,直到根父类析构函数 ,当没有多态的时候,析构函数是这样调用的。

改一下上面的代码:
A * ptr = new C() ;
delete ptr ;
在多态的情况下,如果基类A中的析构函数不是虚构造函数,则当delete ptr的时候只会调用A的析构函数,不会调用B和C中的析构函数;如果A中的析构函数是虚构造函数就会调用所有的析构函数,调用顺序和一般情况一样。

再改一下上面的代码:
B *prt = new C();
delete ptr ;
在多态的情况下,如果A,B中的析构函数都不是虚析构函数,则当delete ptr的时候先调用B的析构函数,再调A的析构函数,不会调用C中的析构函数,如果A或者B中至少有一个是虚析构函数,则析构函数调用和一般情况一样。

因此总结一下规律:
CA * ptr = new CB() ;
delete ptr ;
CB是CA的子类,构造函数的调用一直是一样的,当具备多态的时候:
如果CA及其父类都不具备虚析构函数,则首先调用A的析构函数,然后调用A的父类析构函数直到根父类析构函数,不会调用A以下直到派生类的析构函数 ;如果如果CA及其父类只要有一个具备虚析构函数,则析构函数调用跟一般情况一样。

因此:带有多态性质的基类应该声明虚析构函数 ,这样的基类一般还有其他虚函数;
如果类的设计不是用于基类,而且不具备多态性,则析构函数不应该声明为虚析构函数

小测试代码:

复制代码 代码如下:

#include<iostream>
using namespace std ;

class A
{
public:
A(){cout<<"A constructor"<<endl;}
A(char * arp) { cout <<"not default " ;}

~CA(){cout<<"A desstructor"<<endl;}

};

class B:public A
{
public:
B(){cout<<"B constructor"<<endl;}

~B(){cout<<"B desstructor"<<endl;}
};

class C:public B
{
public:
C(char * arp){cout<<"C constructor"<<endl;}

~C(){cout<<"C desstructor"<<endl;}
};
int main()
{
C * ptr = new C("hello world") ;
delete ptr ;
}

另外effective C++中提到的:
1、
析构函数不能吐出异常,如果析构函数掉用的函数可能产生异常,要在析构函数内部进行捕获进行处理,因为如果析构函数抛出异常的话,比如说vector,当调用各个对象的析构函数进行删除的时候可能导致抛出多个异常,从而使程序进入不确定状态。

2、如果用户需要对某个操作函数运行期间抛出的异常作出反应,那么class应该提供一个普通函数执行这个操作。

3、在构造函数和析构函数中都不应该调用虚函数,这是因为当调用构造函数构造对象的时候,首先会调用父类的构造函数,此时对象的类型在编译器看来就是一个父类对象(实际此时子类成员还处于不确定状态),会调用父类的虚函数,而不会调用子类的虚函数。

时间: 2024-08-20 18:00:19

c++基础语法:构造函数与析构函数_C 语言的相关文章

c++基础语法:构造函数初始化列表_C 语言

C++为类中提供类成员的初始化列表 类对象的构造 顺序是这样的:1.分配内存,调用构造函数 时,隐式/显示的初始化各数据 成员2.进入构造函数后在构造函数中执行一般计算 使用初始化列表有两个原因: 1.必须这样做:如果我们有一个类成员,它本身是一个类或者是一个结构,而且这个成员它只有一个带参数的构造函数,而没有默认构造函数,这时要对这个类成员进行初始化,就必须调用这个类成员的带参数的构造函数,如果没有初始化列表,那么他将无法完成第一步,就会报错. 复制代码 代码如下: class  ABC  .

简单介绍C++编程中派生类的析构函数_C 语言

和构造函数类似,析构函数也是不能被继承的. 创建派生类对象时,构造函数的调用顺序和继承顺序相同,先执行基类构造函数,然后再执行派生类的构造函数.但是对于析构函数,调用顺序恰好相反,即先执行派生类的析构函数,然后再执行基类的析构函数. 请看下面的例子: #include <iostream> using namespace std; class A{ public: A(){cout<<"A constructor"<<endl;} ~A(){cout

详解C++编程中的析构函数_C 语言

C++析构函数 创建对象时系统会自动调用构造函数进行初始化工作,同样,销毁对象时系统也会自动调用一个函数来进行清理工作(例如回收创建对象时消耗的各种资源),这个函数被称为析构函数. 析构函数(Destructor)也是一种特殊的成员函数,没有返回值,不需要用户调用,而是在销毁对象时自动执行.与构造函数不同的是,析构函数的名字是在类名前面加一个"~"符号. 注意:析构函数没有参数,不能被重载,因此一个类只能有一个析构函数.如果用户没有定义,那么编译器会自动生成. 析构函数举例: #inc

全面解析C++中的析构函数_C 语言

"析构函数"是构造函数的反向函数.在销毁(释放)对象时将调用它们.通过在类名前面放置一个波形符 (~) 将函数指定为类的析构函数.例如,声明 String 类的析构函数:~String(). 在 /clr 编译中,析构函数在释放托管和非托管资源方面发挥了特殊作用. 析构函数通常用于在不再需要某个对象时"清理"此对象.请考虑 String 类的以下声明: // spec1_destructors.cpp #include <string.h> class

简要解读C++的动态和静态关联以及虚析构函数_C 语言

C++静态关联与动态关联.C++是怎样实现多态性的 在现实生活中,多态性的例子是很多的.我们分析一下人是怎样处理多 态性的.例如,新生被录取人大学,在人学报到时,先有一名工作人员审查材料,他的职责是甄别资格,然后根据录取通知书上注明的录取的系和专业,将材料转到有关的系和专业,办理具体的注册人学手续,也可以看作调用不同部门的处理程序办理入学手续.在学 生眼里,这名工作人员是总的人口,所有新生办入学手续都要经过他.学生拿的是统一的录取通知书,但实际上分属不同的系,要进行不同的注册手续,这就是多态.那

C++构造函数深度学习_C 语言

本文针对C++构造函数进行深度探究,供大家参考,具体内容如下 1.引子:  以下代码中的输出语句输出0吗,为什么? struct Test { int _a; Test(int a) : _a(a) {} Test() { Test(0); } }; Test obj; cout << obj._a << endl; 输出为:-858993460 2.剖析上面代码的输出为一个垃圾值,也就是说obj调用构造函数并没有对成员进行初始化工作,虽然默认无参构造Test()内部调用了Test

解析C++中构造函数的默认参数和构造函数的重载_C 语言

C++构造函数的默认参数 和普通函数一样,构造函数中参数的值既可以通过实参传递,也可以指定为某些默认值,即如果用户不指定实参值,编译系统就使形参取默认值. [例] #include <iostream> using namespace std; class Box { public : Box(int h=10,int w=10,int len=10); //在声明构造函数时指定默认参数 int volume( ); private : int height; int width; int l

c++类构造函数详解_C 语言

复制代码 代码如下: //一. 构造函数是干什么的 /*   类对象被创建时,编译系统对象分配内存空间,并自动调用该构造函数->由构造函数完成成员的初始化工作     eg: Counter c1;      编译系统为对象c1的每个数据成员(m_value)分配内存空间,并调用构造函数Counter( )自动地初始化对象,初始化之后c1的m_value值设置为0      故:构造函数的作用:初始化对象的数据成员.*/       class Counter       {      publ

C++友元函数与拷贝构造函数详解_C 语言

一.友元函数 1.友元函数概述: (1)友元函数是定义在一个类外的普通函数. 友元函数和普通函数的定义一样;在类内必须将该普通函数声明为友元. (2)友元函数不是成员函数. 不能通过对象来调用,而是直接调用;友元函数可以访问类的公有.受保护以及私有成员,但是必须通过对象.对象指针或者对象引用来访问. 2.友元函数的声明: friend 返回值类型 函数名(参数表); 在类中只需要将这个声明放置在公有部分即可. class Point { double x, y; public: Point(){