- 0
- 0
- 约4.65千字
- 约 17页
- 2018-04-23 发布于河南
- 举报
C程序语言10D
C++程序设计实用教程 清华大学出版社 2008 第10章 构造函数与赋值运算 构造函数 析构函数 拷贝构造函数 赋值运算 组合成员的构造 *趣味程序———模拟银行打印储户存折 小结 10.5 组合成员的构造 既然类是一种数据类型,其对象便可以作为另一个类的数据成员。 即,作为类的数据成员者是另一个类的对象。 称这种情形为类的组合,该数据成员被称为组合成员。 一个很自然的问题是: 组合成员的数据成员由谁来构造? 答案也是很自然的: 自己的事情自己做 ———— 这是C++的一个基本原则。 如何实现自己的事情自己做,具体地: 何时调用组合成员的构造函数? 构造函数的参数如何转递给组合成员的构造函数? 10.5.1 成员的构造时机 对于基本数据类型 double x=3.1415926;// 定义变量并初始化,不是赋值运算 double y; // 定义变量,隐式初始化y = 3.1415926; // 执行赋值运算,不是初始化 // 因为变量y已存在 C++字符串类 class string; 有多个构造函数,如: std::string::string(const char *str=””); std::string::string(const char *str,int n); 有拷贝构造函数实现深拷贝构造 有深赋值运算符函数 有析构函数 10.5.1 成员的构造时机 粗略地,我们说构造函数“完成对象数据空间处理、构造结构、初始化数据成员”。 实际上,Student类的构造函数应该理解为 完成对象数据空间处理、构造结构、初始化数据成员; 再在构造函数体中调整、修改数据成员的值。 那么对象的数据成员究竟在何时创建的? 即,成员的构造时机何在? 用C++语句表述: 其时机应该“在构造函数首部与左花括号之间”! 我们赞叹C++语言设计者的智慧! 10.5.2 组合成员的构造 ——— 冒号语法 我们分析了类的数据成员的初始化时机,并指出了C++语句表述的位置。 显然,构造函数需要接收充分多的参数,然后作为“二传手”将部分参数转递给数据成员的构造函数。 C++具体的语法格式 构造函数名(总参数表) : 组合成员名1(参数表), 组合成员名2(参数表), …{ // 函数体语句} 说明 其实,所有的成员(包括基本数据类型的成员)均通过冒号语法(包括隐式的冒号语法)创建。 数组成员的初始化过程 由隐式的冒号语法创建数组(无法初始化); 由构造函数体语句对数组成员的各元素赋值。 基本数据类型 冒号语法格式中 age(Age), 类比 int a(3), b(a); // C++的新格式是为了满足新需要 等价于 int a=3, b=a; 构造函数体中进一步调整gender的值是为了容错实参 如实参为’M’或’m’,则gender为’m’;否则皆作为’f’ 构造顺序,C++规定 组合成员的构造顺序 先调用组合成员的构造函数,构造组合成员。若有多个组合成员,则依照它们在数据成员描述时声明的顺序构造之,与冒号后面书写顺序无关。 再进入本类的构造函数的函数体,执行函数体语句调整、修改数据成员的值。 冒号语法只能用在构造函数、拷贝构造函数中,位置在函数首部与左花括号之间。 对于那些显式的冒号语法中未提及的数据成员,或者没有使用显式的冒号语法时,系统自动采用隐式的冒号语法,即自动调用相应的默认构造函数构造并初始化数据成员。 析构顺序,C++规定 析构含组合成员的对象时,遵循析构与构造顺序相反的原则。 析构顺序 先执行本对象的析构函数体。 然后执行组合成员的析构函数。有多个组合成员时,按其声明时的相反顺序依次析构。 必须使用显式冒号语法的情形 我们知道 定义常量、声明引用时必须显式地初始化 若某个类没有默认的构造函数,在创建该类对象时必须提供参数进行初始化 故,如下情形必须使用显式的冒号语法 类的常量数据成员 类的引用型成员 无法默认构造的组合成员(其所在的类无默认构造函数) 例10.3 使用冒号语法示例。 class A; 无默认的构造函数,只有一个转换构造函数 class Colonrule; 有成员常量、引用、A的对象等 例10.2(F) 用类string的对象作组合数据成员(正确的程序) 教材中的程序中,设计了 class StringName; 构造函数 拷贝构造函数 赋值运算符函数 析构函数 说明 由于string类设计完善,本例中不必重新定义拷贝构造函数、赋值运算符函数、析构函数。 一个设计完善的类可以像使用基本数据类型一样,即使该类带有资源。 第10章 构造函数 与赋
原创力文档

文档评论(0)