面向对象——类设计(一)
面向对象——类设计(二)
面向对象——类设计(三)
面向对象——类设计(四)
- (1)约定:私有成员函数:以下划线开头,
_
;公有成员函数则不必;
设计顺序
- 类首先是对成员变量的封装;
- 成员函数围绕成员变量展开;
- 成员变量在成员函数之间流转,赋值,被修改;
- 因为可见性(本质是封装性),成员函数的参数一定不会是内部的成员变量,而只能是外部传递进来的变量(或者空参),何苦脱了裤子放屁,多此一举;
信息在类内部的流转
所谓信息,简单说来,就是类所持有的私有成员变量及其值;
因为当前类内部,(私有)成员变量对全部成员函数可见,私有成员会通过不同成员函数的调用顺序进行流转。
构造函数首当其冲,最先被执行。
空参空实现的构造函数
编译器默认提供空参空实现的构造函数,用以初始化全部的成员变量,如果它们存在默认构造的话,但如果显式地提供了其他重载类型的构造方法(包括拷贝构造,不包括赋值构造),则编译器不会再提供该默认构造。
空参空实现构造的含义,在自身的构造之前,使用全部成员变量的默认构造进行私有成员变量的初始化。
禁止创建类实例的方法
- (1)包含纯虚函数的抽象基类
- (2)构造函数声明为 protected()(允许派生类)或 private(派生类也不允许)
protected 型成员
与 private 相比,只对了一个派生类内可见(类内可见),实例不可见,也即不可在外部调用;
派生类构造函数的初始化参数列表
能作为派生类的初始化参数列表的表达式:
-
(1)派生类自身(独有)的非静态数据成员
非静态
好理解,因为静态成员表示的是为类所有,而非某一实例所有。尤其注意自身(独有)
,它不可以是从基类继承而来的数据成员,而只能是自己所独有的、有别于父类的成员。这其实也好理解,既然类构造函数的初始化列表分为两部分,一部分为非静态成员,一部分为基类构造,基类构造构造基类的,非静态的构造自己的。
所以,以上的说明只是对于类构造的初始化参数列表,在类构造的函数体内可对基类的成员做各种访问。
(2)基类
class A
{
public:
A(int v):_v(v){}
// _v 为A所独有
private:
int _v;
};
class B :public A
{
public:
B():_v(0) {}
// 错误,_v为从基类继承而来
B():A(0){}
// 正确
};
适配器(Adapter)与包装类
所谓适配器,必然其内部维护着一个更加底层的类,比如 STL 中的栈(stack)和队列(queue)是对双端队列(deque)的改造(也即是适配),也即在二者的内部,必然维护着双端队列作为自己的内部容器。同样的,包装类也是如此,不然它包装谁去呀。