我在一兩個小時前問過一個類似的問題,但這與我根本不同。在此之後,我應該很好。關於繼承/鑄造的一些最終問題
class base
{
private:
string tame;
public:
void kaz(){}
virtual ~base() {}
void print() const
{
cout << tame << endl;
}
};
class derived: public base
{
private:
string taok;
public:
std::string name_;
explicit derived(const std::string& n) : name_(n) {}
derived(){}
void blah(){taok = "ok";}
void print() const
{
std::cout << "derived: " << name_ << std::endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
base b;
derived d;
base * c = &b;
derived * e = (derived *)&b;
e->kaz();
system("pause");
return 0;
}
我知道在這個例子中向下轉換是不好的做法,但我只是用它作爲一個例子。所以當我現在從一個派生指針指向一個基礎對象時,我不明白爲什麼我仍然能夠執行僅屬於基類的某些操作。
例如,基類的接口有一個Kaz()方法,但派生方法沒有。當我沮喪時,即使Kaz()不是派生類的接口的一部分,爲什麼編譯器不會因爲這樣做而大叫?
爲什麼編譯器在使用派生指針時不會抱怨使用基類成員?
爲什麼只有當我從方法內部訪問基類接口中的成員時,編譯器纔會對我大聲叫嚷?
例如:
我不能做到這一點:
e->print() //Program crashes
但我可以這樣做:如果你仔細看看,沒有
e->tame = "Blah";
cout << e->tame << endl;
沒關係,下面回答。 – Ilya 2010-07-19 22:27:50
派生實例可以訪問所有的基礎成員,因爲您可以繼承並且不重新定義任何。 – Tom 2010-07-19 22:30:35
我downvoted,因爲std :: string的空構造函數將始終初始化爲空字符串。它不是一個未初始化的值,就像他使用過一種基本類型一樣。 – Puppy 2010-07-19 22:33:53