關於C++的子類指標指向父類
阿新 • • 發佈:2018-12-04
1,直接用基類指標引用基類物件
2,直接用派生類指標引用派生類物件
3,用基類指標引用一個派生類物件,由於派生類物件也是基類的物件,所以這種引用是安全的,
但是隻能引用基類成員。若試圖通過基類指標引用那些只在派生類中才有的成員,編譯器會報告語法錯誤。(解決該問題的答案是虛擬函式和多型性)
4,用派生類指標引用基類的物件。這種引用方式會導致語法錯誤。派生類指標必須先強制轉換為基類指標,這種方法是不安全的。
而在侯捷的深入淺出MFC中第二章C++重要性質中:
1、如果你以一個"基類之指標"指向一個"派生類之物件",那麼經由該指標你只能呼叫該基類所定義的函式
2、如果你以一個“派生類之指標”指向一個“基類之物件”,你必須先做明顯的轉型操作(explicit cast),這種作法很危險。
3、如果基類和派生類都定義了“相同名稱之函式”,那麼通過物件指標呼叫成員函式時,到底呼叫了那個函式,必須視該指標的原始型別而定,而不是視指標實際所指的物件的型別而定,這與第1點其實意義相通。
- #include <iostream>
- #include <stdlib.h>
- using namespace std;
- class A
- {
- public:
- char
- void f(){cout<<"class A"<<endl;}
- void fff(){cout<<"class A's str "<<str<<endl;}
- void add(){cout<<"class A address: "
- };
- class B:public A
- {
- public:
- int i;
- char sb[20];
- B(){cout<<"class B constructor is run."<<endl;}
- ~B(){cout<<"class B destructor is run."<<endl;}
- void f(){cout<<"class B"<<endl;}
- void ff(){cout<<"class B "<<i<<str<<sb<<endl;}
- void add(){cout<<"class B address: "<<this<<endl;}
- };
- int main(int argc, char *argv[])
- {
- //宣告父類物件
- A b;
- //宣告父類物件的指標,指向父類物件
- A *pa=&b;
- pa->add();
- //這個寫法正確,不過很危險,因為pa到底是指向B還是A是不確定的.如果能明確的知道
- //pa是指向B類物件的,就如現在寫的這個,那麼沒問題,如果pa指向A類物件,就會存在
- //風險.改變指標的型別,並不會影響記憶體分配既不會呼叫建構函式
- B *pb=(B *)pa;
- //型別強制轉化後,指向的地址相同. 但會按轉化型別訪問資料成員.
- //成員函式屬於類而不屬於物件.各物件共用類的成員函式.強制轉換成 B 型別後,可
- //呼叫類的成員函式。編譯pb->add();後的程式碼只是呼叫add函式的時候傳入了pb的對
- //象指標this
- pb->add();
- //由於pa指向的是父類物件的地址,這個指標被強制轉換為派生類指標後,會出現記憶體越
- //界訪問的情況,是不安全的.
- pb->i=100;
- char dsd[100];
- strcpy(pb->sb, " class B's sb.");
- strcpy(pb->str, " class A's str.");
- //pb->f()呼叫的具體函式,視指標的原始型別而定,而不是視指標實際所指的物件的
- //型別而定.如果是虛擬函式,則視實際所指的物件的型別而定
- pb->f();
- pb->ff();
- pb->fff();
- system("PAUSE");
- return 0;
- }
-