衍生類別對基類的訪問
class Base
{
foo(int);
protected:
int bar;
double foo_bar;
};
class Derived : public Base
{
foo(string);
bool bar(Base *pb);
void foobar();
protected:
string bar;
};
以下錯誤
bool Derived::bar(Base *pb)
{ return foo_bar == pb-> foo_bar; }
通過指向基類對象的指標訪問其受保護的成員難道錯了?
現在讓我們來談談protected這個關鍵字吧,它的意思是:對對象來說,聲明為protected的變數是私人的,而對子類父類來說,聲明為protected的變數是公用的。
衍生類別對其基類類型對象的protected成員沒有特殊存取權限,所以在衍生類別的函數中通過基類的對象來訪問protected成員是非法的
bool Derived::bar(Base *pb) 雖然說形式參數是基類指標,在衍生類別的函數中是不可訪問基類的保護成員,和私人成員.是非法的.
衍生類別的成員可以訪問基類的protected成員(因為衍生類別成員在衍生類別的內部)
衍生類別的對象不可以訪問基類的protected成員(因為衍生類別對象在應用程式定義域,已經出了類內部域)
衍生類別的的對象只能訪問各種類的公有成員,或通過公有成員函數間接訪問私人或受保護的成員
//基類對象對衍生類別對象的切割問題
class Window
{
public:
std::string name() const;
virtual void display() const { cout << "Window.display"; };
};
class WindowWithScrollBars: public Window
{
public:
virtual void display() const { cout << "WindowWithScrollBars.display"; };
};
void printNameAndDisplay(Window w)
{
std::cout << w.name();
w.display();
}
//調用
WindowWithScrollBars wwsb;
printNameAndDisplay(wwsb);
//輸出:
WindowWithScrollBars.display
//當一個derived class 對象以by value 方式傳遞並被視為一個base class 對象,base class 的拷貝建構函式
//會被調用,而“造成此對象的行為像個derived class 對象”的那些特化性質全被切割掉了,僅僅留下一個
//base class 對象,因為正是base class 建構函式建立了它。
// 避免切割問題,可用 pass-by-reference-to-const 代替 pass-by-value。即
void printNameAndDisplay(const Window &w)
{
std::cout << w.name();
w.display();
}