注意的幾點
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.找不到就在上層找。