c++列表提供初始化列表对成员变量进行初始化
#include<iostream>
using namespace std;
class A {
public:
A(int _a) {
a = _a;
cout << "构造函数 " << "a:" << a << endl;
}
~A() {
cout << "析构函数 " << "a:" << a << endl;
}
private:
int a;
};
// 构造函数初始化列表解决: 在B类中 组合了一个 A类对象(A类设计了构造函数)
// 根据构造函数的调用规则: 设计A的构造函数,必须要用,没有机会初始化A
class B {
public:
B(int _b1, int _b2) : a1(1), a2(2) {
}
B(int _b1, int _b2, int m, int n) : a1(m), a2(n), c(0) {
b1 = _b1;
b2 = _b2;
cout << "B构造函数" << endl;
}
~B() {
cout << "B析构函数" << endl;
}
private:
int b1;
int b2;
A a2; // 如果组合对象有多个,按照定义顺序,而不是按照初始化列表顺序
A a1;
const int c;
};
// 先执行 被组合对象的构造函数
// 如果组合对象有多个,按照定义顺序,而不是按照初始化列表顺序
// 析构函数和构造函数调用顺序相反
// 被组合对象的构造顺序 与定义顺序有关系,与初始化列表的顺序没有关系
// 初始化列表用来给const初始
void objplay() {
//A a1(10);
//B objB(1,2);
// 参数传递
B objB2(1, 2, 3, 4);
}
void main() {
objplay();
}
结果
构造函数 a:3
B构造函数
B析构函数
析构函数 a:3
析构函数 a:4
构造析构整体练习
#include <iostream>
using namespace std;
class ABCD
{
public:
ABCD(int a, int b, int c)
{
_a = a;
_b = b;
_c = c;
printf("ABCD() construct, a:%d,b:%d,c:%d \n", _a, _b, _c);
}
~ABCD()
{
printf("~ABCD() construct,a:%d,b:%d,c:%d \n", _a, _b, _c);
}
int getA()
{
return _a;
}
private:
int _a;
int _b;
int _c;
};
class MyE
{
public:
MyE() :abcd1(1, 2, 3), abcd2(4, 5, 6), m(100)
{
cout << "MyE()" << endl;
}
MyE(const MyE& obj) :abcd1(7, 8, 9), abcd2(10, 11, 12), m(100)
{
printf("MyE(const MyE() & obj)\n");
}
~MyE()
{
cout << "~MyE()" << endl;
}
public:
ABCD abcd1; //c++编译器不知道如何构造abc1
ABCD abcd2;
const int m;
};
int doThing(MyE mye1) //mye1 = myE //mye1.拷贝构造函数(myE)
{
printf("doThing() mye1.abc1.a:%d \n", mye1.abcd1.getA());
return 0;
}
int run()
{
MyE myE; //调用的无参构造函数
doThing(myE);
return 0;
}
int main(void)
{
run();
return 0;
}
结果
ABCD() construct, a:1,b:2,c:3
ABCD() construct, a:4,b:5,c:6
MyE()
ABCD() construct, a:7,b:8,c:9
ABCD() construct, a:10,b:11,c:12
MyE(const MyE() & obj)
doThing() mye1.abc1.a:7
~MyE()
~ABCD() construct,a:10,b:11,c:12
~ABCD() construct,a:7,b:8,c:9
~MyE()
~ABCD() construct,a:4,b:5,c:6
~ABCD() construct,a:1,b:2,c:3
匿名对象生命周期立即结束 其他对象在函数结束时生命周期结束
#include <iostream>
using namespace std;
class ABCD
{
public:
ABCD(int a, int b, int c)
{
_a = a;
_b = b;
_c = c;
printf("ABCD() construct, a:%d,b:%d,c:%d \n", _a, _b, _c);
}
~ABCD()
{
printf("~ABCD() construct,a:%d,b:%d,c:%d \n", _a, _b, _c);
}
int getA()
{
return _a;
}
private:
int _a;
int _b;
int _c;
};
class MyE
{
public:
MyE() :abcd1(1, 2, 3), abcd2(4, 5, 6), m(100)
{
cout << "MyE()" << endl;
}
MyE(const MyE& obj) :abcd1(7, 8, 9), abcd2(10, 11, 12), m(100)
{
printf("MyE(const MyE() & obj)\n");
}
~MyE()
{
cout << "~MyE()" << endl;
}
public:
ABCD abcd1; //c++编译器不知道如何构造abc1
ABCD abcd2;
const int m;
};
int doThing(MyE mye1) //mye1 = myE //mye1.拷贝构造函数(myE)
{
printf("doThing() mye1.abc1.a:%d \n", mye1.abcd1.getA());
return 0;
}
int run2()
{
printf("run2 start..\n");
ABCD(400, 500, 600); //临时对象的⽣命周期 //会产生一个临时的匿名对象。
//再次析构匿名对象 //匿名的临时对象,编译器会立刻销毁。不等到正常函数调用完毕。,
ABCD abcd = ABCD(100, 200, 300);
printf("run2 end\n");
//在此析构abcd
return 0;
}
int main(void)
{
run2();
return 0;
}
结果
run2 start..
ABCD() construct, a:400,b:500,c:600
~ABCD() construct,a:400,b:500,c:600
ABCD() construct, a:100,b:200,c:300
run2 end
~ABCD() construct,a:100,b:200,c:300
构造函数中调用构造函数
#include<iostream>
using namespace std;
// 构造函数中调用构造函数因为匿名对象,容易产生错误
class MyTest {
public:
MyTest(int a, int b, int c) {
this->a = a;
this->b = b;
this->c = c;
}
MyTest(int a, int b) {
this->a = a;
this->b = b;
MyTest(a, b, 100);
}
~MyTest() {
cout << "~MyTest()" << "a:" << a << " b:" << b << " c:" << c << endl;
}
int getC() const { return c; }
void setC(int val) { c = val; }
private:
int a;
int b;
int c;
};
void main() {
MyTest t1(1, 2);
cout << "c: " << t1.getC() << endl;
}
结果
~MyTest()a:1 b:2 c:100
c: -858993460
~MyTest()a:1 b:2 c:-858993460