C++学习笔记之 构造函数的初始化列表

来源:互联网 发布:pptv网络电视官方下载 编辑:程序博客网 时间:2024/06/06 15:38
<span style="font-family: Arial, Helvetica, sans-serif;">// 20160220 note</span>
/* 知识点:构造函数的初始化列表 1.根据构造函数的调用规则 设计A的构造函数必须要使用!!!如果在B的类中定义了A的对象,就必须要调用A的构造函数进行初始化。 语法: Constructor::Constructor():a1(m),a2(n),a3(v1,v2)... 2.先执行 被组合对象的构造函数,也就是该例子中的A类的对象 如果组合对象有多个,则按照定义的顺序,而不是按照初始化列表的顺序来执行 析构函数的顺序和构造函数调用顺序相反*/#include "stdafx.h"#include <iostream>using namespace std;class A{public:A(int _a){a = _a;cout << "执行A构造函数" << endl;}~A(){cout << "执行A析构函数" << endl;}private:int a;};class B{public:B(int _b1,int _b2):a1(1),a2(2){cout << "执行B构造函数" << endl;b1 = _b1;b2 = _b2;}B(int x, int y, int m, int n):a1(m),a2(n){b1 = x;b2 = y;cout << "执行B构造重载函数" << endl;}~B(){cout << "执行B析构函数" << endl;}private:int b1;int b2;A a1;A a2;};void playObjB(){B b(1, 2, 3, 4);}int _tmain(int argc, _TCHAR* argv[]){playObjB();return 0;}

构造函数和析构函数调用顺序的综合练习:

// 构造和析构函数综合练习.cpp : 定义控制台应用程序的入口点。#include <iostream>using namespace std;class ABCD{public:ABCD(int a,int b,int c,int d){this->a = a;this->b = b;this->c = c;this->d = d;cout << endl;cout << "调用ABCD构造函数" << endl;cout << "this->a:" << this->a << " " << "this->b:" << this->b << " ""this->c:" << this->c << " ""this->d:" << this->d << " ";}~ABCD(){cout << endl;cout << "调用ABCD析构函数" << endl;}int getA(){return this->a;}private:int a;int b;int c;int d;};class MyE{public:MyE() :abcd1(1, 2, 3, 4), abcd2(5, 6, 7, 8), m(10){cout << endl;cout << "MyE构造函数调用" << endl;}~MyE(){cout << endl;cout << "MyE构造函数调用" << endl;}MyE(const MyE&obj) :abcd1(11, 12, 13, 14), abcd2(15, 16, 17, 18), m(20){cout << endl;cout << "MyE拷贝构造函数调用" << endl;}int getM(){return m;}private:ABCD abcd1;ABCD abcd2;const int m;};void doThing(MyE mye1){cout << endl;cout << "doThing myE" << endl;cout << mye1.getM() << endl;}int run(){printf("run() start\n");MyE mye;doThing(mye);//此时用实参赋值给形参,会调用myE类的拷贝构造函数printf("run() end\n");return 0;}int _tmain(int argc, _TCHAR* argv[]){run();return 0;}

答案如下:


匿名对象的生命周期训练

// 构造和析构函数综合练习.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <iostream>using namespace std;class ABCD{public:ABCD(int a,int b,int c,int d){this->a = a;this->b = b;this->c = c;this->d = d;cout << endl;cout << "调用ABCD构造函数" << endl;cout << "this->a:" << this->a << " " << "this->b:" << this->b << " ""this->c:" << this->c << " ""this->d:" << this->d << " ";}~ABCD(){cout << endl;cout << "调用ABCD析构函数" << endl;}int getA(){return this->a;}private:int a;int b;int c;int d;};class MyE{public:MyE() :abcd1(1, 2, 3, 4), abcd2(5, 6, 7, 8), m(10){cout << endl;cout << "MyE构造函数调用" << endl;}~MyE(){cout << endl;cout << "MyE构造函数调用" << endl;}MyE(const MyE&obj) :abcd1(11, 12, 13, 14), abcd2(15, 16, 17, 18), m(20){cout << endl;cout << "MyE拷贝构造函数调用" << endl;}int getM(){return m;}private:ABCD abcd1;ABCD abcd2;const int m;};void doThing(MyE mye1){cout << endl;cout << "doThing myE" << endl;cout << mye1.getM() << endl;}int run01(){printf("run() start\n");MyE mye;doThing(mye);//此时用实参赋值给形参,会调用myE类的拷贝构造函数printf("run() end\n");return 0;}int run02(){//匿名对象或临时对象,因为没有对象去接它,因此当调用一次构造函数后,就会调用析构函数。//ABCD(100, 200, 300, 400);临时对象的声明周期只存在于69行。//如果匿名对象有对象去接,那么匿名对象就转正了,当return 0后才会调用析构函数。也不会调用拷贝构造函数,因为是转正不是赋值。ABCD abcd = ABCD(100,200,300,400);return 0;}int _tmain(int argc, _TCHAR* argv[]){int ret=run02();return 0;}


0 0