关于C++对象模型的一点理解(2)

先帖段代码,再慢慢分析吧

// project1.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include<string.h>

struct A{
    A(){puts("A()");};//默认构造函数
    A(int v){puts("A(int)");};//重载构造函数
    A(const A&){puts("A(A&)");};//拷贝或复制构造函数
    A& operator=(const A &){//赋值构造函数
        puts("operator=(A&)");
        return *this;
    }
    ~A(){puts("~A()");}
};

struct X{
    X(int v){
        a=v;
    }
    A a;
    ~X(){puts("~X()");};
};
int main(){
  X slow(int(2));
  return 0;
}


输出结果为下图

下面具体分析下C++都做了什么。。。

代码执行到X slow(int(2))的时候,当执行到X(int v),首先执行初始化列表,然后在执行函数体之前初始化成员变量,当然这里的初始化列表没有内容,所以没有执行什么,然后此时会先初始化该类的成员变量,也就是A a,于是会打印第一个A(),接下来进入X的构造函数体,执行a=v,由于v是int类型,此时C++编译器会做隐式类型转换,通过A(int)构造函数构造出一个临时对象,用v进行初始化,所以会打印第二句A(int),接下来才会执行赋值运算符,打印第三句operator=(A&),当来到X(int)的函数体尾部,这个临时对象会被析构,于是打印了第四句~A(),析构时会按照构造函数的逆序先执行~X()函数,然后再析构成员变量,于是分别打印出~X(),~A()。

于是整个流程大致为:X(int)   --->   初始化列表   -->    成员变量   -->   X(int)函数体   -->   创建临时对象A(int),A.operator=(),~A()  -->  按逆序析构

作为成员变量与继承的对比,下面再帖一段相似的继承的例子

struct X2:public A{
    X2(int v){
        a=v;
    }
    A a;
    ~X2(){puts("~X2()");};
};
int main(){
  X2(int(2));
  return 0;
}


此时输出结果如下

打印的结果与上述相比,仅仅在上述的结果首尾多了个A()和~A()。这是因为基类的初始化是在初始化列表之前,析构也是在最后.

原文地址:https://www.cnblogs.com/abc123456789/p/3433451.html