C++ primer Plus第十章总结
最重要的OPP特性有
- 抽象
- 封装和数据隐藏
- 多态
- 继承
- 代码的可重用性
C++用class来定义类设计,格式如下
class stock
{
..................
}
其中stock是这个类的类型名,我们可以使用stock来声明类的对象,如stock a; stock b;
访问控制
private 表示私有成员,public表示公有成员,程序可以直接访问公有成员,但是只能通过公有成员函数(或者友元函数)访问私有成员。一般而言,数据项通常放在私有部分,组成类接口的成员函数放在公有部分。private 可以不写出,这是对类对象的默认访问控制。
实现类成员函数
- 定义类成员函数的时候,使用作用域解析运算符(::)来识别函数所属的类
- 类方法(成员函数)可以访问private组件
例如,我们定义stock类中的update函数,我们可以使用以下方法对其进行声明
void stock::update()
{
}
使用update()的方法 : stock::update();
定义在类声明的函数都是内联函数,声明再类声明中的函数如果在类之外定义的时在函数前使用 inline,函数也会变成内联函数。
对象使用成员函数的方法:
例如 stock kate,joe;则使用成员函数的方法可以如下
kate.update();;
joe.update();
类的构造函数与析构函数
由于类的数据部分是私有的,所以我们不能用常规的初始化语法初始类初始化类对象。
类构造函数是类中的一个特殊的成员函数,专门用于构造新对象,把值赋予给他们的数据成员,构造函数没有声明类型。
声明和定义类构造函数
如下图
声明(在类声明中完成,一般是在.h文件中):
定义(一般在..c文件中):
使用构造函数
用构造函数初始化对象的方式有以下几种
1.显式地调用构造函数
stock food=stock("world cabbage",250,1.25);
2.隐式地调用构造函数
stock garment(“Furry Mason”,50,2.51);
3.使用new与构造函数一起初始化类对象
stock *pstock=new stock("elec",18,19.0);
默认构造函数
默认构造函数是在未提供显示初始值时,用来创建对象的构造函数,也就是说,它是用于下面这种声明的构造函数
stock fluffy_the_cat;
这样子有用的原因是,如果没有提供任何构造函数,C++会自动提供默认构造函数。它是默认构造函数的隐式版本,不做任何工作。对于stock类来说,默认构造函数可能如下:
stock::stock(){}
定义默认构造函数的两种方法
1.为已有构造函数提供默认参数
stock(const string &co="Error",int n=0,double pr=0.0)
2.通过函数重载来定义另一个构造函数
stock();
由于只能有一个默认构造函数,所以不要同时采用这两种方法。
创建默认构造函数之后,便可以声明对象而不对他进行显式的初始化,如:
stock first;
stock *prelief=new stock;
析构函数
析构函数的作用实在对象过期的时候自动完成清理作用,就好比我们使用new开辟了一个内存之后,在使用完后我们需要使用delete来清除
析构函数的声明
析构函数和构造函数一样,也没有类型,析构函数的声明如下
~stock();
由于析构函数不承担任何重要的工作,可以将它编写成不执行任何操作的函数
stock::~stock()
{
}
当然,这不代表这其中不可以添加执行函数。
析构函数不需要显式地调用,一般如果创建的是静态存储类对象,则析构函数是在程序结束的时候被自动调用的,如果创建的是自动存储类对象,那么程序会在执行完代码块的时候被调用,如果是使用new创建的,那么它会存储在*存储区,使用delete 的时候会自动调用析构函数,如果程序员没有提供析构函数,那么编译器将隐式地声明一个析构函数,并在需要的时候自动调用。
构造函数和析构函数小结
大家可以参考这篇文章
https://www.jianshu.com/p/638aebc8175b
this指针
this指针值指向用来调用成员函数的对象,例如,stock类中有成员函数topval(). stock1,stock2为stock类对象,那么,如果我们调用stock1.topval(stock2),那么this指针指向stock1。
对象数组
对象数组的声明方法和声明标准类型数组相同,如下
stock mystuff[4];
其调用成员函数的方法如下
mystuff[0].update();
类作用域
在类中定义的名称的(如类成员函数名和类数据成员名)的作用域为整个类,作用域为整个类的名称在类中是已知的,在类外不可知,所以在不同类对象之间可以有相同的成员函数名
如何声明所有类中都通用的常量
1.我们可以使用枚举
class Backery
{
private:
enum{Month=12};
double const[Month];
}
这种方式声明的枚举并不会创建数据成员,也就是说,所有的对象中都不包含枚举,在作用为整个类的代码中遇到它,编译器会用12来代替。
2.使用关键字static
例如:
class backry
{
private:
static const int month =12;
.........
}
month常量和静态变量存储在一起,不会存储在对象之中,可以被所有的backry变量共享。
作用域内枚举
传统的枚举存在一些问题,其中之一是两个枚举定义中枚举量可能发生冲突。假设有一个处理鸡蛋和T恤的项目,其中可能包含类似下面这样的代码;
enum egg{small,medium,large};
enum T-short{small,medium,large};
这将无法通过编译,因为egg和T-short位于相同的作用域中,他们将发生冲突。C++11提供了一种新枚举,其枚举的作用域为类,这种枚举的声明如下
enum class egg{small,medium,large};
enum class T-short{small,medium,large};
其使用方法如下
egg choice=egg::large;
T-short choice=T-short::large;
枚举量的作用域为类后,不同枚举定义中的枚举量就不会发生名称冲突了。