C++primer 第七章 类(有关类的相关定义)
类的基本思想:数据抽象和封装。数据抽象是一种依赖于接口和实现分离的编程技术。类的接口包括用户所能执行的操作;类的实现则包括类的数据成员、负责接口实现的函数体以及所需的各种私有函数。封装实现了类的接口和实现的分离(用自己的话讲,就是封装把类的实现隐藏了,别人已将功能的实现帮你完成了,你只需要直接调用)。
1.定义抽象数据类型:
类作用域:类本身就是一个作用域。
编译器分两步处理类:首先编译成员的声明;然后才是成员函数体。
A.定义read和print函数:
read函数:是从给定流中将数据读到给定的对象里;(istream输入流,读取和写入操作会改变流中的内容,从而一般定义为普通引用)
例如:
Sales_data::Sales_data(istream &is)
{
read(is,*this) //read函数的作用是从is中读取一条交易信息然后存入this对象中
}
print函数:是负责将给定对象的内容打印到给定流中;(ostream输出流,对内容的打印,从而可以定义为常量引用)
B.构造函数
构造函数的定义:类通过一个或多个特殊成员函数来控制对象的初始化过程;
用法:构造函数的名字和类名相同;它没有返回类型;(另外补充析构函数的用法:同样和类名相同,只是在类名前面加~符号)
默认构造函数:前面章节也有提到,类通过一个特殊的构造函数来控制默认初始化过程;(默认构造函数无需任何实参)
默认构造函数的用法:
例如:
Sales_data()=default;
就是在无实参的构造函数后面加=default;
构造函数的唯一目的:为数据成员赋初始值;
2.访问控制与封装
类中public和private的访问权限,pubilc访问权限:类中成员在整个程序中可被访问;private访问权限:可以被定义类的成员访问,也可以被友元函数访问。(后面章节15章会做详细的讲解)
class与struct区别(也是唯一区别):默认权限不同。class默认类的成员为private,而struct默认类的成员为public。
友元:它可以访问类的非公有成员,从而作用是 增加函数的访问权限。
用法:在类中声明的函数前面加friend;(友元声明)
封装的优点:一是确保用户代码不会无意间破坏封装对象的状态。二是被封装的类的具体实现细节可以随时改变,而无需调整用户级别的代码。
3.类的作用域
A.名字查找与类的作用域
名字查找:首先,在名字所在的块中寻找其声明语句,只考虑在名字的使用之前出现的声明。如果没找到,继续查找外层作用域;如果最终没有找到匹配的声明,则程序报错。
B.类型名要特殊处理:在类中,如果成员使用外层作用域的某个名字,而该名字代表一种类型,则类不能在之后重新定义该名字。
例子:
typedef double money;
class Account{
public:
money balance() {return bal;} //使用外层作用域的money;
private:
typedef double money; //错误:不能重新定义money;
money bal;
};
4.构造函数再探
A.构造函数初始值列表
就对象的数据成员而言,初始化和赋值也有类似的区别。如果没有在构造函数的初始值列表中显示地初始化成员,则该成员将在构造函数整体之前执行默认初始化。
如果成员是const、引用,或者属于某种未提供默认构造函数的类类型,我们必须构造函数初始值列表为这些成员提供默认初值。
B.explicit构造函数
explicit只对一个实参的构造函数有效。它只能用于直接初始化;
5.类的静态成员
类的静态成员的定义:用static去声明成员函数,静态数据成员不属于类的任何一个对象,类似于全局变量(不属于某个对象所有,它属于整个类)。
优点:一是避免与其他类成员或全局对象名字冲突;二是实施封装。
静态成员与普通成员的区别:
一是静态数据成员的类型可以是它所属的类类型,而非静态数据成员则受到限制,只能声明成它所属类的指针或引用;
二是静态成员可以默认实参;
总结c++11特性:
1.默认构造函数=default的使用
(前面已经做了详细讲解;)
2.委托构造函数
定义:一个委托构造函数使用它所属类的其他构造函数执行它自己的初始化过程;(把自己的职责委托给了其他构造函数)
例子:
class Sales_data{
public:
Sales_data(string s,unsigned cnt,double price);
bookNo(s),unit_sold(cnt), revenue(cnt*price){ }
//其余构造函数全部委托给另一个构造函数
Sales_data():Sales_data("",0,0) { }
Sales_data(string s): Sales_data(s,0,0) { }
Sales_data(istream &is): Sales_data()
{ read(is,*this); }
};
当一个构造函数委托给另外一个构造函数时,受委托的构造函数的初始值列表和函数体被依次执行。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。