1.基類中成員的繼承
在某本書上看到「子類擁有父類所有非private的屬性和功能」,當時就在想,那private的成員和方法呢?能被繼承嗎?
上網搜了好久,各種說法都有,有的說不能繼承;有的說能繼承,但是不能訪問;有的說不能訪問,所以不能算繼承………………
後來自己寫了幾段**來驗證了一下。
首先宣告,我並不知道繼承的具體定義是什麼,也不知道基類的成員在子類中表現出來的這種特性算不算繼承,所以本文將盡量不使用「繼承」這個詞
1.1 基類的私用成員在派生類中是存在的
這個可以用**驗證如下:
#include using namespace std;
class animal
animal(const string &name) : _name(name)
void jiao() const
private:
string _name;
};class cat : public animal
cat(const string &name) : animal(name)
};int main()
**1.1
在ubuntu10.04下用g++編譯執行的結果如下:
mapuser@ubuntu:~/documents$ g++ test1.cc
mapuser@ubuntu:~/documents$ ./a.out
i`m an animal, my name is miaomiao
可以看到派生類cat中確實存在基類animal的私有變數_name。
1.2基類的私有成員在派生類中不能直接訪問,只能通過公有的方法來訪問
驗證**如下:
#include using namespace std;
class animal
animal(const string &name) : _name(name)
void jiao() const
void setname(const string &name)
string getname() const
private:
string _name;
};class cat : public animal
cat(const string &name) : animal(name)
};int main()
**1.2 animal類增加了方法setname和getname,主函式加了幾句話。
這段**編譯結果如下:
mapuser@ubuntu:~/documents$ g++ test1.cc
test1.cc: in function 『int main()』:
test1.cc:20: error: 『std::string animal::_name』 is private
test1.cc:35: error: within this context
編譯出錯,說_name是私有變數。
把第35行,即
mycat._name = "mimi";
注釋掉,再編譯:
mapuser@ubuntu:~/documents$ g++ test1.cc
mapuser@ubuntu:~/documents$ ./a.out
i`m an animal, my name is miaomiao
mimi
如果覺得不好理解。。我覺得可以這樣模擬一下,cat不是animal的派生類,而是乙個全新的類,不過cat類中有乙個成員是animal類的例項:
class cat ;
所以cat類中有animal的全部成員,但是不能直接訪問私有變數。
當然這肯定是不對的,只能用來幫助理解吧 ╮(╯▽╰)╭
2.多型和虛函式
以前一直沒搞懂一件事情:在基類中定義乙個函式func,派生類又定義了乙個一樣的(返回型別和引數型別)函式func;此時基類中的函式func宣告為虛函式和沒有宣告為虛函式到底有什麼區別?。。。
首先注意這樣乙個事實:可以用派生類來初始化指向基類的指標或引用,以上述animal和cat類為例:
以下語句是合法的
animal *pa;
cat mycat("miaomiao");
pa = &mycat;
animal &ra = mycat;
**2.1
但是為什麼可以這樣呢?因為派生類中含有基類的全部資訊。所以當用派生類來初始化指向基類的指標或引用時,指向的是派生類中的基類部分。如圖:
animal: | virtual func1; func2 |
cat : | virtual func1; func2 | func2 |
上圖中cat類包含了animal;類的兩個函式func1和func2,其中func1是虛函式,func2不是虛函式,cat還自己定義了func2。
**2.1中的pa和ra指向的都是cat中的前面那一部分。
那麼多型和虛函式是怎麼回事呢?
個人理解如下:
animal中的func1定義為虛函式,在cat類中對其進行重寫,重寫的func1函式將替換cat類中屬於基類部分的func1。
animal中俄func2沒有定義為虛函式,在cat類中對其進行重寫(這個是不是叫重寫?),重寫的func2並不替換cat類中屬於基類不封的func2,而是在cat自己的空間生成這個func2
所以ra和pa呼叫func1將呼叫cat中重寫的函式,呼叫func2將呼叫animal中的func2。
驗證**如下:
#include using namespace std;
class animal
animal(const string &name) : _name(name)
virtual void jiao() const
void zou() const
protected:
string _name;
};class cat : public animal
cat(const string &name) : animal(name)
void jiao() const
void zou() const
};int main()
**2.2
編譯執行結果如下:
mapuser@ubuntu:~/documents$ g++ test1.cc
mapuser@ubuntu:~/documents$ ./a.out
i`m an animal, my name is aaa
i`m an animal, i`m walking
i`m a cat, my name is ccc
i`m an animal, i`m walking
C 繼承與多型之虛函式
一 定義 虛函式必須是基類的非靜態成員函式,其訪問許可權可以是private或protected或public,在基類的類定義中定義虛函式的一般形式。虛函式是一種在基類定義為virtual的函式,並在乙個或多個派生類中再定義的函式。實現多型性。虛函式的特點是,只要定義乙個基類的指標,就可以指向派生類...
C 繼承 多型 虛函式
c 支援多繼承 class parent class parent2 class child public parent,private parent2公有繼承和私有繼承的區別 public parent 公有繼承,private和public都會繼承 private parent 私有繼承,只繼承...
C 繼承 多型 虛函式 抽象
一 繼承 1 如果你以乙個 基類指標 指向 派生類物件 那麼經由該指標你只能呼叫基類所定義的函式 2 如果你以乙個 派生類指標 指向乙個 基類指標 你必須先做明顯的轉型操作。3 如果基類和派生類都定義了相同名稱的成員函式,那麼通過物件指標呼叫成員函式是,到底呼叫到那乙個函式,必須視該指標的原始型別而...