7.3.1 类成员再探
定义类型别名
typedef std::string::size_type pos;
或者是
using pos = std::string::size_type;
用来定义类型的成员必须先定义后使用,这一点与普通成员函数相区别,因此,类型成员通常出现在类开始的地方
包含头文件的形式#include "Screen.h",一定要用" ", 而不能用< >
成员函数重载,编译器根据实参的数量来决定运行哪个版本的函数
char get() const
{
return contents[cursor]; //返回光标当前位置的字符
}
inline char Screen::get(pos r, pos c) const
{
pos row = r * width;
return contents[row + c]; // 返回指定返回指定光标位置的字符
}
可变数据成员
public:
void some_member() const;
private:
mutable size_t access_ctr = 0; //定义一个可变的size_t类型的数据成员
void Screen::som2_member() const
{
++access_ctr;
}
如果display()的返回类型是类类型,那么在它之后还可调用其他成员函数,如:
myScreen.display(cout.set(4, 5, '#')); //先输出后置位
返回引用的函数是左值的,意味着这些函数返回的是对象本身而非对象的副本。如果我们把一系列这样的操作连接在一起的话,所有这些操作将在同一个对象上得到执行。若返回类型并非引用类型,则每次不断返回操作后的副本 ,用调用运算符链接的一些列操作可以达到预期的操作效果,但是如果分开来写则达不到预期的效果,因为每次都是返回一个执行了操作的副本,原对象并未作任何改变。
7.3.3类类型
即使两个成员列表完全一致,他们也是不同的类型。对于一个类来说,它的成员和其他任何类的成员都已不是一回事。
类的声明:
我么可以仅仅声明类而暂时不定义它:
Class Screen // Screen 类的声明
这种类型有时被称作前向声明,对于类型Screen来说,在它声明之后完全定义之前是一个不完全类型。也就是说,此时我们已知Screen是一个类类型,但是不清楚它到底包含哪些成员。
不完全类型只能在非常有限的情景下使用:可以定义指向这种类型的指针或引用。也可以声明(但是不能定义)以不完全类型作为参数或者返回类型的函数。对于一个类来说,在我们创建它的对象之前该类必须被定义过,而不能仅仅被声明。否则,编译器就无法了解这样的对象需要多少内存空间。
7.3.4 友元再探
每个类负责控制自己的友元类或友元函数
如果一个类想把一组重载函数声明成它的友元,他需要对这组函数每一个分别声明。
下面这段代码最重要的是理解友元声明的作用是影响访问权限,它本身并非普通意义上的声明。
struct X {
friend void f() {/*友元函数可以定义在类的内部*/};
X() { f(); } //错误,找不到标识符,f()还没被声明
void g();
void h();
};
void X::g() { return f(); } //错误,找不到标识符,f()还没被声明
void f(); //声明那个定义在X中的函数
void X::h() { return f(); } // 正确:现在f()的声明在作用域中了