对象成员特点总结:

(1)实例化对象A时,如果对象A有对象成员B,那么先执行对象B的构造函数,再执行A的构造函数。

(2)如果对象A中有对象成员B,那么销毁对象A时,先执行对象A的析构函数,再执行B的析构函数。

(3)如果对象A中有对象成员B,对象B没有默认构造函数,那么对象A必须在初始化列表中初始化对象B(原因:因为实例化A时,会先执行B的构造函数,再执行A的构造函数,如若对象B没有默认构造函数,即需要给B的构造函数传递参数才能调用,但是此时A的构造函数还没有执行,因此它还拿不到A构造函数的参数,所以先调用B的构造函数这个过程将无法进行。而初始化列表会先于构造函数的执行对对象成员进行初始化,因此不必再担心B的构造函数拿不到参数而无法执行的问题。因此如果B没有默认构造函数,那么对象A必须在初始化列表中初始化对象B.)

也许有人说 直接在a类的构造函数里“写死”b类构造函数的参数不就可以了吗,但这样的话不同a类对象里的b类对象的参数是固定的,而通过初始化列表的方式,则可以在定义a类对象时,为b类对象的构造参数传入参数,该参数是可以改变的,所以c++在设计的时候,就直接把前者摒弃掉,出现这种情况直接报错(个人看法)

类A和B的关系就好比是汽车和零部件的关系,实例化类A就相当于产生汽车的过程,肯定要先生产零部件再组装生成汽车,因此构造的时候先构造对象成员类B,再构造类A。

销毁对象就跟销毁汽车的过程类似,必须先销毁汽车才能取其零部件,因此先调用类A的析构函数销毁类A,再销毁其对象成员类B。

具体由下面的代码演示,可直接RUN。

#include <iostream>using namespace std;
class Coordinate
{public:
Coordinate(int x, int y):m_iX(x),m_iY(y)//把a类的参数传递给b类
{cout<<"Coordinate() "<<m_iX<<","<<m_iY<<endl;
}~Coordinate(){cout<<"~Coordinate() "<<m_iX<<","<<m_iY<<endl;}// 打印坐标的函数
void printInfo()
{cout<<"("<<m_iX<<","<<m_iY<<")"<<endl;
}
public:
int m_iX;
int m_iY;
};class Line
{public:Line(int x1,int y1,int x2,int y2):m_coordA(x1,y1),m_coordB(x2,y2){cout<<"Line()"<<endl;}~Line(){cout<<"~Line()"<<endl;}void printAB(){cout<<"("<<m_coordA.m_iX<<","<<m_coordA.m_iY<<")"<<endl;cout<<"("<<m_coordB.m_iX<<","<<m_coordB.m_iY<<")"<<endl;}public:Coordinate m_coordA;Coordinate m_coordB;
};
int main(void)
{Line * line = new Line(1,2,3,4);line->printAB();delete line;return 0;
}运行结果如下:Coordinate() 1,2
Coordinate() 3,4
Line()
(1,2)
(3,4)
~Line()
~Coordinate() 3,4
~Coordinate() 1,2

下面是直接“写死”的做法,编译也无法通过

#include <iostream>using namespace std;
class Coordinate
{public:
Coordinate(int x, int y):m_iX(x),m_iY(y)
{cout<<"Coordinate() "<<m_iX<<","<<m_iY<<endl;
}~Coordinate(){cout<<"~Coordinate() "<<m_iX<<","<<m_iY<<endl;}// 打印坐标的函数
void printInfo()
{cout<<"("<<m_iX<<","<<m_iY<<")"<<endl;
}
public:
int m_iX;
int m_iY;
};class Line
{public:Line(int x1,int y1,int x2,int y2){cout<<"Line()"<<endl;}~Line(){cout<<"~Line()"<<endl;}void printAB(){cout<<"("<<m_coordA.m_iX<<","<<m_coordA.m_iY<<")"<<endl;cout<<"("<<m_coordB.m_iX<<","<<m_coordB.m_iY<<")"<<endl;}public:Coordinate m_coordA(1,2);    //类A里直接定义B类对象(B类没有无参构造函数),而不通过初始化列表,这种写法是错误的Coordinate m_coordB(3,4);
};
int main(void)
{Line * line = new Line(1,2,3,4);line->printAB();delete line;//Coordinate m_coordA(1,2);    直接定义Coordinate类的对象就没有问题return 0;
}编译出错
topeet@ubuntu:~$ g++ test.cpp -o test
test.cpp:45: error: expected identifier before numeric constant
test.cpp:45: error: expected ‘,’ or ‘...’ before numeric constant
test.cpp:46: error: expected identifier before numeric constant
test.cpp:46: error: expected ‘,’ or ‘...’ before numeric constant
test.cpp: In member function ‘void Line::printAB()’:
test.cpp:41: error: ‘((Line*)this)->Line::m_coordA’ does not have class type
test.cpp:41: error: ‘((Line*)this)->Line::m_coordA’ does not have class type
test.cpp:42: error: ‘((Line*)this)->Line::m_coordB’ does not have class type
test.cpp:42: error: ‘((Line*)this)->Line::m_coordB’ does not have class type

参考文章:https://blog.csdn.net/hudfang/article/details/50511481

C++经典问题:如果对象A中有对象成员B,对象B没有默认构造函数,那么对象A必须在初始化列表中初始化对象B?相关推荐

  1. 3-6:类与对象下篇——构造函数中的初始化列表、匿名对象和explicit关键字

    文章目录 (1)真的是初始化吗 (2)初始化列表 A:概述 B:哪些成员必须在初始化列表进行初始化 (3)注意 (4)匿名对象 (5)explicit关键字 (1)真的是初始化吗 前文中,我们使用构造 ...

  2. java for 获取索引_获取Java列表中的对象索引

    我的(Android)Java程序中有一个字符串列表,我需要获取列表中对象的索引.问题是,我只能找到有关如何查找对象的第一个和最后一个索引的文档.如果我的列表中有3个或更多相同的对象怎么办?我怎样才能 ...

  3. List 列表中的对象在循环中的声明问题

    请看下面两段代码..MessageTopic对象建立的位置,直接导致了保存在List中MessageTopic对象的改变 第一段代码 public static List<MessageTopi ...

  4. C++类和对象成员函数,静态成员,构造函数和析构函数、初始化列表

    类和对象 数据成员的访问 定义成员函数 调用成员函数 私有成员函数 构造函数和析构函数 构造函数成员初始化列表 在构造函数中使用new的注意事项 this指针 const成员函数 运算符重载 友元函数 ...

  5. 【黑马程序员 C++教程从0到1入门编程】【笔记4】C++核心编程(类和对象——封装、权限、对象的初始化和清理、构造函数、析构函数、深拷贝、浅拷贝、初始化列表、友元friend、运算符重载)

    黑马程序员C++教程 文章目录 4 类和对象(类属性[成员属性],类函数[成员函数]) 4.1 封装 4.1.1 封装的意义(三种权限:public公共.protected保护.private私有)( ...

  6. C++阶段03笔记02【类和对象(封装、对象的初始化和清理、对象模型和this指针、友元、运算符重载、继承、多态)】

    C++| 匠心之作 从0到1入门学编程[视频+课件+笔记+源码] 目录 1.内存分区模型 2.引用 3.函数提高 4.类和对象 4.1.封装 4.1.1.封装的意义 --实例1:设计圆类 --实例2: ...

  7. 初始化列表||类对象作为类成员|| 静态成员

    初始化列表 作用: C++提供了初始化列表语法,用来初始化属性 语法:构造函数():属性1(值1),属性2(值2)... {} #include <iostream> using name ...

  8. 对象的初始化列表const变量的初始化

    当B类中有A类并且A类还有自己的有参数构造函数的时候,那这时若是B再使用默认构造函数就不能使用了,因为B不能对A进行初始化: #include <iostream> using names ...

  9. Java虚拟机(四)—— Java虚拟机中的对象

    1. Java 对象在虚拟机中的生命周期 在 Java 对象被类加载器加载到虚拟机中后,Java 对象在 Java 虚拟机中有 7 个阶段. 1.1 创建阶段(Created) 创建阶段的具体步骤为: ...

最新文章

  1. python爬取音乐神器_Python爬虫提取神器,正则表达式(re模块),全程干货!
  2. 论文浅尝 | 变分知识图谱推理:在KG中引入变分推理框架
  3. 德媒看2019年的世界:西方在争吵,中国在崛起,非洲在增长……
  4. kafka中topic默认属性_分享:Kafka 的 Lag 计算误区及正确实现
  5. css阻止换行_CSS中,如何处理短内容和长内容?
  6. 13.mysql架构方案_MYSQL常见架构
  7. jredis和letucce_深入理解Redis(一)——高级键管理与数据结构
  8. 22. 栈的压入、弹出队列(C++版本)
  9. sort colors 三色排序
  10. Luogu1919 【模板】A*B Problem升级版(FFT快速傅里叶)
  11. 初学Python选什么版本?
  12. 【wpa_supplicant】driver如何告诉supplicant自己做的一些事情以及结果
  13. win10计算机打开速度慢,win10电脑速度突然很慢怎么处理
  14. linux 关闭系统自动更新,Linux下如何关闭自动更新
  15. 迪杰斯特拉算法(dijkstra)
  16. 生成小学算术题——小程序
  17. 项目动态|Apache Pulsar 2.10.0 版本介绍
  18. 中国前10名的休闲服品牌企业信息化漫谈--S公司
  19. NLP 中文分词-双向匹配算法(理论+Python实现)
  20. spooling技术和通道及实现打印机共享

热门文章

  1. oracle11g 修改字符集 修改为ZHS16GBK
  2. 4种常见的 PHP 设计模式
  3. Android之封装好的异步网络请求框架
  4. mysql语句在node.js中的写法
  5. 基于visual Studio2013解决C语言竞赛题之1049抓牌排序
  6. 扩大swap分区--Ubuntu手记之系统配置
  7. [导入]Ajax使用初步
  8. 今天开始学C#.NET
  9. 链表快速排序python_Python一行代码实现快速排序的方法
  10. java setcontenttype_response.setContentType()在Java过滤器中重置