对象成员特点总结:

(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. 批量实现面向对象的实例
  2. html5纪念日期代码,HTML5适合的情人节礼物有纪念日期功能
  3. python判断队列是否为空_[python模块]队列queue
  4. powerdesigner 同步mysql 报错_Win7下PowerDesigner连接mysql,反向工程,导出差异脚本,或直接同步...
  5. 世界上最奇异的10种树,你都见过吗?
  6. ubuntu下软件中心闪退问题解决
  7. Eclipse 使用常见问题汇总
  8. linux如何安装阵列卡驱动程序,Linux安装阵列卡驱动及档.doc
  9. 9、网络详解 学习笔记
  10. Android Touch 事件的分发和消费机制
  11. 剑指offer总目录
  12. 403. 青蛙过河--(每日一难phase2--day10)
  13. 集成电路和芯片的联系与区别
  14. 06-输出100以内的素数
  15. excel求回归直线方程的公式_如何用excel快速求线性回归方程?
  16. 小三角箭头向下向上查看隐藏的效果 vue
  17. Spring Boot实训开发个人博客9 - 标签管理
  18. 这个冬季,你抑郁吗?
  19. 一款可自定义自动字典生成器---火花
  20. 【通知】4月18日22:00至4月19日2:00网站服务暂停公告

热门文章

  1. oracle11g 修改字符集 修改为ZHS16GBK
  2. DOM 基础 HTML标签 元素 属性
  3. 每天自动给自己发天气预报的脚本
  4. 《Two Dozen Short Lessons in Haskell》(二十)分数
  5. 好消息,关于2005的default provider
  6. linux php7 mongodb,CentOS 7下安装配置PHP7跟LAMP及MongoDB和Redis
  7. java se程序设计_JavaSE--Java 的基本程序设计结构
  8. python超市售货统计程序_用Python实现简易超市售货系统
  9. Linux监控CPU关闭服务器,监控Linux服务器CPU和内存
  10. dw空心圆项目符号_如何懂建筑施工图?搞懂这些符号解析,耐下性子研究不会学不会...