C++ 12.1 类的定义、声明、成员函数、数据成员
2015-06-17 14:42
344 查看
简介
数据成员一般声明为private,以实现信息的隐蔽成员函数一般声明为public,以提供外界使用的接口
构造函数一般声明为public,以便创建类的对象
创建一个类类型的对象时,编译器会自动使用一个构造函数来初始化该对象,构造函数是一个特殊的、与类同名的成员函数,用于初始化每个数据成员来设置初始值。
构造函数一般使用一个构造函数初始化列表,来初始化对象的数据成员
构造函数初始化列表由成员名和带括号的初始值组成,跟在构造函数的形参表之后,并以冒号开头。
Sale_item(const double&re,unsigned &us_sol):units_sold(us_sol),revenue(re){}
在类内部,声明成员函数是必需的,而定义成员函数则可选,可以在类外定义。在类内部定义的函数默认为inline 函数
-在类外部定义的成员函数必须指明它们是在类的作用域中。
double Sale_item::avg_price() const //在类外定义avg_price()函数,必须加上类的作用域 Sale_item::,double 是返回值类型 {}
将关键字const 加在形参表之后,就可以将成员函数声明为常量,const成员不能改变其所操作的对象的数据成员。const 必须同时出现在声明和定义中!!!!
用struct关键字和class关键字定义的类区别:
class中如果没有指明,那么默认为private,struct则默认为public
struct和class一样,也可以有构造(constructor)函数、析构(destructor)函数,之间也可以继承
对于一个空类,编译器默认产生4个成员函数:默认构造函数、析构函数、拷贝构造函数和赋值函数(13/14章)(p104面试宝典)
因为static成员不是任何对象的组成部分,所以static成员函数不能声明为const.毕竟,将成员函数声明为const就是承若不会修改该函数所属的对象。最后,static成员函数也不能声明为虚函数(15.2.4)。(12.6节)
声明为const的成员函数是没法修改数据成员的,这时候我们可以把数据成员声明为mutable类型,这样就可以修改了。
私有的mutable类型数据成员,任然是无法通过对象直接的,还是需要成员函数来访问的。(12.2)
==========================================================================================
在C++中,用类来定义自己的抽象数据类型。通过定义类型来对应所要解决的问题中的各种概念,可以更加容易编写、调试和修改程序
12 章 : 类作用域、构造函数以及this 指针、友元、可变成员和静态成员。
从第1章开始,我们就已经开始使用类。标准库类型:vector、istream、string都是类类型。 还有自己定义的Sale_item 类。
class Sale_item{ public: double avg_price() const; //声明了一个const 成员函数 bool same_isbn(const Sale_item &rhs) const {return isbn==rhs.isbn;} Sale_item():units_sold(0),revenue(0.0){}//构造函数 private: std::string isbn; unsigned units_sold; double revenue; }; double Sale_item::avg_price() const //在类外定义avg_price()函数,必须加上类的作用域,以及const限定符 { if(units_sold) return revenue/units_sold; else return 0; }
一、类定义
类就是定义了一个新的类型和一个新的作用域。对于一个空类,编译器默认产生4个成员函数:默认构造函数、析构函数、拷贝构造函数和赋值函数(13/14章)(p104面试宝典)
class Student{ public: };
1、类成员—-所有成员必须在类内部声明,一旦类定义完成后,就没有别的方式增加成员了
每个类可以没有成员,也可以定义多个成员,成员可以是数据和函数或类型别名一个类可以包含若干公有的、私有的和受保护的部分。public、private、protected
所有成员必须在类内部声明,一旦类定义完成后,就没有别的方式增加成员了。
数据成员一般声明为private,以实现信息的隐蔽
成员函数一般声明为public,以提供外界使用的接口
构造函数一般声明为public,以便创建类的对象
2、构造函数—-与类同名的成员函数,用于初始化每个数据成员来设置初始值。
创建一个类类型的对象时,编译器会自动使用一个构造函数来初始化该对象,构造函数是一个特殊的、与类同名的成员函数,用于初始化每个数据成员来设置初始值。构造函数一般使用一个构造函数初始化列表,来初始化对象的数据成员
-构造函数初始化列表由成员名和带括号的初始值组成,跟在构造函数的形参表之后,并以冒号开头。
Sale_item():units_sold(0),revenue(0.0){}
//也可以是 Sale_item(const double&re,unsigned &us_sol):units_sold(us_sol),revenue(re){}
3、成员函数—-必须在类内声明,但可以在类外定义,在类内定义的默认为inline函数
在类内部,声明成员函数是必需的,而定义成员函数则可选,可以在类外定义。在类内部定义的函数默认为inline 函数-在类外部定义的成员函数必须指明它们是在类的作用域中。
成员函数都有一个隐含的实参,将函数绑定到调用函数的对象,当我们编写函数 trans.avg_price()时,就是在调用名为trans的对象的avg_price函数。如果trans是一个Sale_item对象,则在avg_price函数内部对Sale_item类成员的引用就是对trans成员的引用。
将关键字const 加在形参表之后,就可以将成员函数声明为常量,const成员不能改变其所操作的对象的数据成员。const 必须同时出现在声明和定义中!!!!
虽然声明为const的成员函数是没法修改数据成员的,这时候我们可以把数据成员声明为mutable类型,这样就可以修改了。
私有的mutable类型数据成员,任然是无法通过对象直接的,还是需要成员函数来访问的。(12.2)
因为static成员不是任何对象的组成部分,所以static成员函数不能声明为const.毕竟,将成员函数声明为const就是承若不会修改该函数所属的对象。最后,static成员函数也不能声明为虚函数(15.2.4)。
double Sale_item::avg_price() const //在类外定义avg_price()函数,必须加上类的作用域 {}
用struct关键字和class关键字定义的类区别:
class中如果没有指明,那么默认为private,struct则默认为public
struct和class一样,也可以有构造(constructor)函数、析构(destructor)函数,之间也可以继承
二、数据抽象和封装
类背后的思想是数据抽象和封装数据抽象是一种依赖于接口和实现分离的技术,使用该类的程序员不必了解这些细节。他们只需要考虑该类型做什么而不需要考虑该类型如何工作。
封装是一项将低层次的元素组合起来形成新的、高层次实体的技术。函数是封装的一种形式,函数所执行的细节行为被封装在函数本身这个更大的实体中。被封装的元素隐藏了它们的实现细节——可以调用一个函数但不能访问它所执行的语句。同样地,类也是一个封装的实体:它代表若干成员的聚集,大多数(良好设计的)类类型隐藏了实现该类型的成员。
标准库类型vector同时具备数据抽象和封装的特性,在使用方面是抽象的,只需考虑他的接口,即执行的操作。但它又是封装的,因为我们既无法了解该类型如何表示的细节,也无法访问其任意的实现制品。另一方面,数组概念类似于vector,但既不是抽象的,也不是封装的。
1、访问标号实施抽象和封装—public、private
在c++中,使用访问标号来定义类的抽象接口和实施封装。一个类可以没有访问标号,也可以包含多个访问标号:程序所有部分都可以访问带有public 标号的成员。类型的数据抽象视图由其public成员定义;
使用类的代码不可以访问带有private标号成员。private封装了类型的实现细节。
-一个访问标号可以出现的次数没有限制。每个访问标号指定了随后的成员定义的访问级别。这个指定的访问级别持续有效,直到遇到下一个访问标号或看到类定义体的右花括号为止。
-可以在任意的访问标号出现之前定义类成员。在类的左花括号之后、第一个访问标号之前定义成员的访问级别,其值依赖于类是如何定义的。如果类是用struct关键字定义的,则在第一个访问标号之前的成员是公有的:如果类时用class关键字定义的,则这些成员私有。
如果类中某成员的定义之前没有出现任何访问标号,则在用class定义的类中,成员默认为private成员。struct 关键字定义的类中,成员默认为public成员
并非所有类型都必须是抽象的,标准库中的pair类就是一个实用的、设计良好的具体类而不是抽象类,具体类会暴露而非隐藏其实现细节。
一些类,例如pair ,确实没有抽象接口。pair类型只是将两个数据成员酷捆绑成单个对象。在这种情况下,隐藏数据成员没有必要。
这样的类型通常还有成员函数,特别的,如果类具有内置类型或复合类型数据成员,那么定义构造函数来初始化这些成员就是一个好主意。
2、编程角色的不同类别
3、数据抽象和封装的好处
数据抽象和封装提供了两个优点:避免类内部出现无意的、可能破坏对象状态的用户级错误。
随时间推移可以根据需求改变或缺陷报告来完善类实现,而无须改变用户级代码。
改变头文件中的类定义可以有效地改变包含该头文件的每个源文件的程序文本,所以,当类发生改变时,使用该类的代码必须重新编译
相关文章推荐
- 《The Design and evolution of C++》读书笔记1
- 收藏:c语言的多线程同步
- C语言sscanf的用法总汇
- LeetCode 200. Number of Islands
- C++11 标准新特性: 右值引用与转移语义
- C/C++ char和int的区别
- C++函数模板使用中的注意事项
- 学长们的求职血泪史(C/C++/JAVA)
- VC++在一个类中调用另一个类中的函数
- 精确度问题
- PAT分支-15. 日K蜡烛图(15) C语言作答
- c++_单实例模式
- 请输出以下4*5矩阵
- C/C++编译器编译过程和头文件包含错误解决方案
- C++写一个简单的解析器(分析C语言)
- POJ 2196 Specialized Four-Digit Numbers
- C++中new,delete使用注意事项
- C++中const、volatile、mutable的用法
- C++重载运算符
- C++ 临时对象