請看下面一個完整的例子:
#include
using namespace std;
class A{
public:
int n;
A(int n):n(n){}
void display(){ cout<<"Class A: n="<<n<<endl;}
};
class B: public A{
public:
B(int n):A(n){}
void display(){ cout<<"Class B: n="<<n<<endl;}
};
class C: public A{
public:
C(int n):A(n){}
void display(){ cout<<"Class C: n="<<n<<endl;}
};
int main(){
A a(1);
B b(2);
C c(3);
a.display();
a = b;
b.n = 100;
a.display();
a = c;
a.display();
return 0;
}
運行結(jié)果:
Class A: n=1
Class A: n=2
Class A: n=3
本例中灾测,將 b 對象賦值給 a 對象茫死,等價于 a.n = b.n著蛙,賦值完成后 a.n 的值為 2瞧壮,然后調(diào)用 a.display() 函數(shù)煞檩,輸出結(jié)果就是”Class A: n=2“低缩。將 c 對象賦值給 a 對象也是同樣的道理损俭。
這個例子很好的說明了:基類對象和派生類對象之間的賦值僅僅是對應(yīng)的成員變量的賦值音五,不會影響成員函數(shù)辣恋,不會影響 this 指針亮垫。
指向?qū)ο蟮闹羔?br>
對上例 main 函數(shù)中的代碼做如下更改:
A *p = new A(1);
p->display();
p = new B(2);
p->n = 100;
p->display();
p = new C(3);
p->display();
輸出結(jié)果:
Class A: n=1
Class A: n=100
Class A: n=3
本例定義了一個指針,使它指向不同的對象伟骨。與上例不同的是饮潦,本例中并沒有發(fā)生對象的賦值,僅僅是改變了指針的指向携狭。
將 p 指向 B 類的對象继蜡,隱式指針 this 也隨之改變,指向 B 類的對象逛腿,所以 p->n 和 this->n 訪問的都是 B 類對象的成員變量稀并,輸出結(jié)果顯然是”n=100“。
細心讀者可能已經(jīng)發(fā)現(xiàn)单默,雖然 this 指向了 B 類對象碘举,但是 p->display() 依然調(diào)用 A 類的成員函數(shù)。這是因為搁廓,成員變量和成員函數(shù)不在同一個內(nèi)存區(qū)域引颈,系統(tǒng)通過 this 指針來訪問成員變量耕皮,但是卻不通過它來訪問成員函數(shù)。
如果希望通過 p 指針訪問 B類的成員函數(shù)蝙场,可以將該成員函數(shù)聲明為虛函數(shù) 凌停,詳情看第四章。