- 类和成员
一个类就是一个用户自定义类型,由一些内置类型、其他用户自定义类型以及一些函数所组成。
用来定义类的组成部分称为成员。一个类可以有零个或多个成员。
class X{
public:
int m;//数据成员
int mf(int v) {int old = m; m = v; return old;}//函数成员
};
类成员的访问使用符号object.member
X var;
var.m = 7;
int x = var.mf(9);
- 接口与实现
class X{ //类的名字为X
public:
//共有成员:
//用户接口,可以被所有人访问
//函数
//类型
//数据,通常最好为private
private:
//私有成员:
//实现细节,仅能被该类的成员访问
//函数
//类型
//数据
};
类成员默认是私有的,也即:
class X{
int mf(int);
//...
};
等价于
class X{
private:
int mf(int);
//...
};
因此,错误如下:
X x;
int y = x.mf();//错误,mf是私有的,不能直接访问
用户不能直接访问一个私有成员,应通过一个公有函数来访问,例如:
class X{
int m;
int mf(int);
public:
int f(int i) {m=i;return mf(i);}
};
X x;
int y = x.f(2);
如果仅仅用来描述数据、没有私有实现细节的类,用结构(struct)来表示。
一个结构就是一个成员默认为公有属性的类:
struct X{
int m;
//...
};
即为:
class X{
public:
int m;
///...
};
成员函数:将函数声明于类体内,作为类的成员。
构造函数:与类同名的成员函数为特殊的成员函数,专门用于对类对象进行初始化。
struct Date{
int y,m,d;
Date(int y,int m,int d);//构造函数,进行初始化
void add_day(int n);
};
Date my_bitrhday;//错误,未进行初始化
Date last {2000,12,31};//正确
Date next = {2014,2,14};//正确,比较啰嗦
Date christmas = Date{1976,12,24};//正确,更啰嗦的一种显示创建对象
保持细节私有性
将不希望用户更改的元素置于private之中。
在设计类型时,设法保证合法值。
对象的值通常称为状态(state),因此合法值的思想也被称为对象的合法状态(valid state)。
判定合法值的规则称为不变式定义成员函数
class Date {
public :
Date(int y, int m, int d);
void add_day(int n);
int month();
private:
int y, m, d;
};
Date::Date(int yy, int mm, int dd)//构造函数
:y{ yy }, m{ mm }, d{ dd }//成员初始化
{
}
当然,成员初始化也可以这样写:
Date::Date(int yy, int mm, int dd)
{
y = yy;
m = mm;
d = dd;
}
也可以将初始化写在类声明中,不过这样会过于“凌乱”,可读性不好。但是,对于简单、较小的函数,则考虑在类声明中给出其定义。
同时需要注意的是,类成员对其他成员的访问并不依赖与成员在类中的声明位置。也就是说,“名字必须在使用之前声明”在类内有限作用域是放宽的。
总之,除非明确需要从小函数的内联中获得性能增益,否则就不要讲成员函数体放在类声明之中。