类里的一些特性
注意的几点
1.可以在类里定义类型别名,受访问级别约束。
class Screen
{
public:
typedef string::size_type pos;
};
class Screen
{
public:
using pos = string::size_type;
};
2.成员函数声明为inline时,声明和定义里有一个标记为inline就行。
3.如果你返回*this,就把返回值弄成引用类型,可以链式调用。
class Screen //内容写的不严谨
{
public:
Screen & set(char c);
Screen() = default;
private:
int width = 0, height = 0, cursor = 0;
string contents;
};
inline Screen& Screen::set(char c)
{
contents[cursor] = c; //得确定这里不会缓冲区溢出
return *this;
}
这样就可以可以链式调用:
myScreen.move(4,0).set('#'); //改的还是myScreen
如果返回Screen,而不是Screen &,则上句等价于下面这个:
temp = myScreen.move(4,0);
temp.set('#'); //这里改的是temp
4. const成员函数的this是const *const,所以return *this;返回的是常量引用,无法接着链式调用。
myScreen.display(cout).set('#'); //xxx,myScreen.display(cout)是常量引用,无法调用非const函数(打破约束)
5. const成员函数(代表this指针有顶层属性,具有可区分不同函数能力)可以重载
class Screen
{
public:
Screen &display()
{
}
const Screen &display() const
{
return *this;
}
};
调用display函数时,对象const属性决定调用哪个。
Screen myscreen1();
const Screen myscreen();
myscreen1.set('#').display(); //调用的是非const版本
myscreen2.display(); //调用的是const版本,注意一调用set就报错
类类型
有个有意思的东西,类只要没被定义完就是不完全类型。
指针和引用可以用,但类型本身不能用。
class A
{
A a; //xxx,不能用不完全类型
A *prev;
A *next;
};
类的作用域
假如在类外用到用到类里声明的东西,需要加上类名::。
class Window_mgr
{
public:
using ScreenIndex = std::vector<Screen>::size_type; //类型
void clear(ScreenIndex i);
ScreenIndex addScreen(const Screen&);
};
void Window_mgr::clear(ScreenIndex i) //ScreenIndex自动会在在类里找
{}
Window_mgr::ScreenIndex Window_mgr::addScreen(const Screen&) //一般先查返回类型,所以得自己加Window_mgr::
{}
为了保险起见,你该加类作用域的地方都自己加上。
名字查找
分离编译
1. 类里先编译所有声明(成员变量和函数声明)
2. 再编译类里的函数体。
查找规则
1.先在当前块里找,只找名字前的声明。
2.找不到就在上层找。