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

(0)

相关推荐

  • C++类成员构造函数和析构函数顺序示例详细讲解

    对象并不是突然建立起来的,创建对象必须时必须同时创建父类以及包含于其中的对象.C++遵循如下的创建顺序: (1)如果某个类具体基类,执行基类的默认构造函数. (2)类的非静态数据成员,按照声明的顺序创建. (3)执行该类的构造函数. 即构造类时,会先构造其父类,然后创建类成员,最后调用本身的构造函数. 下面看一个例子吧 复制代码 代码如下: class c{public:    c(){ printf("c\n"); }protected:private:}; class b {pub

  • c++类构造函数详解

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

  • 解析C++中虚析构函数的作用

    我们知道,用C++开发的时候,用来做基类的类的析构函数一般都是虚函数.可是,为什么要这样做呢?下面用一个小例子来说明:    有下面的两个类: 复制代码 代码如下: class ClxBase{public:    ClxBase() {};    virtual ~ClxBase() {};    virtual void DoSomething() { cout << "Do something in class ClxBase!" << endl; };}

  • 深入C++中构造函数、拷贝构造函数、赋值操作符、析构函数的调用过程总结

    1 . 用同一个类的源对象构造一个目标对象时,会调用拷贝构造函数来构造目标对象,如果没有定义拷贝构造函数,将调用类的默认拷贝函数来构造目标对象.2 . 当一个函数的返回值为一个类的对象时,如果在调用函数中,没有定义一个对象来接收这个返回对象值,会用返回一个临时对象保存返回对象的值.在被调用函数结束时,这个临时对象被销毁.而当调用函数中有一个接受对象时,就将返回对象赋值给接收对象,这个返回对象在调用函数结束时调用析构函数.3. 当类有一个带有一个参数的构造函数时,可以用这个参数同类型的数据初始化这

  • 详解C++中如何将构造函数或析构函数的访问权限定为private

    今天面试被问到了这个单例模式常用到的技术手段,下面进行分析:         很多情况下要求当前的程序中只有一个object.例如一个程序只有一个和数据库的连接,只有一个鼠标的object.通常我们都将构造函数的声明置于public区段,假如我们将其放入private区段中会发生什么样的后果?这意味着什么?         当我们在程序中声明一个对象时,编译器为调用构造函数(如果有的话),而这个调用将通常是外部的,也就是说它不属于class对象本身的调用,假如构造函数是私有的,由于在class外

  • C++函数返回值为对象时,构造析构函数的执行细节

    看如下代码: 复制代码 代码如下: #include<iostream>class TestConstructor{public:    TestConstructor()    {        std::cout<<"TestConstructor()"<<std::endl;    }    ~TestConstructor()    {        std::cout<<"~TestConstructor()"

  • 深入解析C++中的构造函数和析构函数

    构造函数:在类实例化对象时自动执行,对类中的数据进行初始化.构造函数可以从载,可以有多个,但是只能有一个缺省构造函数. 析构函数:在撤销对象占用的内存之前,进行一些操作的函数.析构函数不能被重载,只能有一个. 调用构造函数和析构函数的顺序:先构造的后析构,后构造的先折构.它相当于一个栈,先进后出. 复制代码 代码如下: #include<iostream>#include<string>using namespace std;class Student{ public:  Stud

  • C++中构造函数与析构函数的调用顺序详解

    前言 在使用构造函数和析构函数时,需要特别注意对它们的调用时间和调用顺序.在一般情况下,调用析构函数的次序正好与调用构造函数的次序相反:最先被调用的构造函数,其对应的(同一对象中的)析构函数最后被调用,而最后被调用的构造函数,其对应的析构函数最先被调用. 简单来说,其构造函数的顺序就一句话: 基类构造函数 -> 成员的构造函数 -> 构造函数体内语句 看下面一个代码示例: #include <iostream> using namespace std; class A { publ

  • C++中拷贝构造函数的总结详解

    1.什么是拷贝构造函数: 拷贝构造函数嘛,当然就是拷贝和构造了.(其实很多名字,只要静下心来想一想,就真的是顾名思义呀)拷贝又称复制,因此拷贝构造函数又称复制构造函数.百度百科上是这样说的:拷贝构造函数,是一种特殊的构造函数,它由编译器调用来完成一些基于同一类的其他对象的构建及初始化.其唯一的参数(对象的引用)是不可变的(const类型).此函数经常用在函数调用时用户定义类型的值传递及返回. 2.拷贝构造函数的形式 复制代码 代码如下: Class X{public: X(); X(const

  • 从汇编看c++的默认析构函数的使用详解

    c++中,如果没有为一个类提供析构函数,那么编译器会为这个类提供默认的析构的函数.由于析构函数的功能和构造函数相反,因此和默认的构造函数类似,编译器也会提供无用的默认的析构函数,和非无用的析构函数.两者的分析情况一样(对于默认的构造函数分析,请参看<从汇编看c++中默认构造函数的使用分析>).并且编译器会提供非无用的默认析构函数情形和默认构造函数类似: 1 类含有虚成员函数(类继承自虚基类或者继承的基类含有虚成员函数,也属于这种情况) 2 类继承自一个基类,基类含有自定义析构函数(如果基类没有

随机推荐