第三天之多个对象构造和析构
1、对象初始化列表
1)对象初始化列表出现原因
1.必须这样做:
如果我们有一个类成员,它本身是一个类或者是一个结构,而且这个成员它只有一个带参数的构造函数,没有默认构造函数。这时要对这个类成员进行初始化,就必须调用这个类成员的带参数的构造函数,
如果没有初始化列表,那么他将无法完成第一步,就会报错。
2、类成员中若有const修饰,必须在对象初始化的时候,给const int m 赋值
当类成员中含有一个const对象时,或者是一个引用时,他们也必须要通过成员初始化列表进行初始化,
因为这两种对象要在声明后马上初始化,而在构造函数中,做的是对他们的赋值,这样是不被允许的。
2)C++中提供初始化列表对成员变量进行初始化
语法规则
Constructor::Contructor() : m1(v1), m2(v1,v2), m3(v3)
{
// some other assignment operation
}
3)注意概念
初始化:被初始化的对象正在创建
赋值:被赋值的对象已经存在
4)注意:
成员变量的初始化顺序与声明的顺序相关,与在初始化列表中的顺序无关
初始化列表先于构造函数的函数体执行
#define _CRT_SECURE_NO_WARNINGS
#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类的构造函数必须要用,用B定义对象时没有机会初始化A
//新的语法:Constructor::Contructor() : m1(v1), m2(v1, v2),m3(v3)
class B
{
public:B(int _b1, int _b2) : a1(1), a2(2), c(0){}B(int _b1, int _b2, int m, int n) : a1(m), a2(n), c(0){b1 = _b1;b2 = _b2;}~B(){cout << "B的析构函数" << endl;}
private:int b1;int b2;A a1;A a2;const int c; //如果有const变量,在参数列表中初始化
};//二、执行顺序:
//先执行被组合对象的构造函数
//如果组合对象有多个,按照定义顺序而不是按照初始化列表的顺序//析构函数 和构造函数的调用顺序相反//三、被组合对象B的顺序与定义顺序有关系,与初始化列表的顺序没有关系
void obj10play()
{//A a1(10);//B objB(1, 2);//1、参数传递B objB2(1, 2, 3, 4);//2、调用顺序return;
}void main()
{obj10play();cout << "hello" << endl;system("pause");
}
2、强化训练
#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++编译器不知道如何构造abc1ABCD 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 run2()
{printf("run2 start..\n");//直接调用构造函数将会产生匿名对象ABCD(400, 500, 600); //临时对象的⽣命周期只存在于这句话 //会产生一个临时的匿名对象。//再次析构匿名对象 //匿名的临时对象,编译器会立刻销毁。不等到正常函数调用完毕。,ABCD abcd = ABCD(100, 200, 300);printf("run2 end\n");//在此析构abcdreturn 0;
}int main(void)
{run();//run2();return 0;
}
匿名对象的生命周期
直接调用构造函数将会产生匿名对象
int main(void)
{//run();run2();return 0;
}
在构造函数中调用构造函数(产生匿名对象)
在构造函数中调用构造函数是一种危险的行为
#include <iostream>
using namespace std;
//构造中调⽤构造是危险的⾏为class MyTest
{
public:MyTest(int a, int b, int c) //有参 构造函数{_a = a;_b = b;_c = c;}MyTest(int a, int b) //有参数的构造函数,两个参数{_a = a;_b = b;//构造函数中,无法嵌套构造函数 来通过构造函数给自己的成员变量赋值,//此构造函数已经又创建了另一个对象。MyTest(a, b, 100); //产⽣新的匿名对象//新的匿名对象 a->1 b->2 c ->100}~MyTest(){printf("MyTest~:%d, %d, %d\n", _a, _b, _c);}int getC(){return _c;}void setC(int val){_c = val;}private:int _a;int _b;int _c;
};int main()
{MyTest t1(1, 2); //t1.a -->1 t1.b -->2 t1.c--->? printf("c:%d\n", t1.getC()); //请问c的值是?return 0;
}
第三天之多个对象构造和析构相关推荐
- c++多个对象构造和析构
多个对象构造和析构 对象初始化列表 对象初始化列表出现原因 注意概念 注意 总结 对象初始化列表 对象初始化列表出现原因 1.必须这样做: 如果我们有一个类成员,它本身是一个类或者是一个结构,而且这个 ...
- C++对象模型8——构造函数和析构函数中对虚函数的调用、全局对象构造和析构、局部static数组的内存分配
一.构造函数和析构函数中对虚函数的调用 仍然以https://blog.csdn.net/Master_Cui/article/details/109957302中的代码为例 base3构造函数和析构 ...
- glibc全局构造与析构(解释了_do_global_ctors_aux)----写的相当不错!!!
原文地址::http://www.xuebuyuan.com/839077.html 11.4 C++全局构造与析构 在C++的世界里,入口函数还肩负着另一个艰巨的使命,那就是在main的前后完成全 ...
- C++之临时对象的构造与析构
1.临时对象产生的时间点 对象作参数(值传递).返回对象(值传递) 2.临时对象析构的时间点(重点.难点) 3.临时对象会降低效率,但是哪些情况必须使用临时对象? [注]真正的临时对象是看不见的,它不 ...
- $emit传递多个参数_10年架构师深解java核心技术:方法参数+对象构造,确定不学?...
方法参数 首先回顾一下在程序设计语言中有关参数传递给方法(或函数)的一些专业术语.值调用(call by value)表示方法接收的是调用者提供的值.而引用调用(call by reference)表 ...
- C++内存分配与对象构造的分离
在C++中,我们基本用new(delete)操作符分配(释放)内存.new操作符为特定类型分配内存,并在新分配的内存中构造该类型的一个对象.new表达式自动运行合适的构造函数来初始化每个动态分配的类类 ...
- 【C++从入门到踹门】第三篇:类和对象(中)类的默认成员函数
目录 1.类的默认成员函数 2.构造函数 2.1 构造函数引入 2.2 构造函数概念及特点 3. 析构函数 3.1 析构函数引入 3.2 析构函数的概念 3.3 在哪些情况下会程序会执行析构函数? 3 ...
- GprMax2D ——媒体和对象构造命令
#medium: #box: #cylinder: #x_segment: #y_segment: #triangle: 本节将讨论GprMax2D中可用的命令,以便于在模型中引入不同的介质以及构造特 ...
- (黑马C++)L03 对象的构造和析构
对象的初始化和清理 构造函数和析构函数会被编译器自动调用,完成对象初始化和对象清理工作.即使自己不提供初始化操作和清理操作,编译器也会增加默认的操作,所以编写类就应该顺便提供初始化函数. 构造函数和析 ...
最新文章
- Nginx配置文件nginx.conf详解(转)
- HTML的xmlns的作用
- mysql数据库参数
- 如何用PPT来实现三维3D效果,附参数设置详解
- Mac下 javac java 进行编译和运行含有包路径及引入jar包的类
- 在vs2010 .net 4.0 引用dll .net 2.0(转)
- 实例化Spring容器的两种常用方式
- IDEA添加新项目到SVN
- java实训总结_JAVA实训总结
- 如何在苹果手机上进行自动化测试!!!!!可以尝试配置一下
- 天牛须和贪心算法_利用天牛须搜索算法(BAS)优化PID控制器参数的代码
- react中请求网络图片加载不出来的问题 解决
- 基于迭代情绪交互网络的对话情绪识别
- java 调用felix_使用eclipse开发felix的OSGI插件
- oracle dblink 验证,oracle通过dblink查询sqlserver报错
- Android 开发挑战赛 | 第 2 周: 倒计时器
- Python基于php+MySQL的英语四六级在线报名平台
- 2021年江西省上饶市高考成绩查询,2021年上饶高考状元名单公布,上饶文理科状元是谁多少分...
- PHP 安装与配置及Apache关联
- 随笔 - 58, 文章 - 0, 评论 - 0, 引用 - 0 三次握手 四次握手 与socket函数的关系