日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

将派生类指针赋值给基类的指针

發布時間:2025/4/5 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 将派生类指针赋值给基类的指针 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

除了可以將派生類對象賦值給基類對象(對象變量之間的賦值),還可以將派生類指針賦值給基類指針(對象指針之間的賦值)。我們先來看一個多繼承的例子,繼承關系為:

#include <iostream>using namespace std;//基類class A{public:A(int a);int m_a; public:void display();};A::A(int a):m_a(a) {}void A::display() {cout<<"Class A:m_a="<<m_a<<endl; }//派生類class B:public A{public:B(int a1,int b);public:void display();protected:int m_b; };B::B(int a, int b):A(a),m_b(b) {}void B::display() {cout<<"Class B:m_a="<<m_a<<", m_b"<<m_b<<endl;}class C{ public:C(int c);public:void display();protected:int m_c;};C::C(int c):m_c(c){}void C::display() {cout<<"Class C: m_c="<<m_c<<endl;}class D:public B,public C{public:D(int a,int b,int c,int d);public:void display();private:int m_d;};D::D(int a, int b, int c, int d) :B(a,b),C(c),m_d(d){}void D::display() {cout<<"Class D: m_a="<<m_a<<", m_b="<<m_b<<", m_c="<<m_c<<", m_d="<<m_d<<endl; }int main(){A *pa =new A(1);B *pb =new B(2,20);C *pc =new C(3);D *pd =new D(4,40,400,4000);pa=pd;pa ->display();pb=pd;pb ->display();pc=pd;pd ->display();cout<<"-----------------------"<<endl;cout<<"pa="<<pa<<endl;cout<<"pb="<<pb<<endl;cout<<"pc="<<pc<<endl;cout<<"pd="<<pd<<endl;return 0;} Class A:m_a=4 Class B:m_a=4, m_b40 Class D: m_a=4, m_b=40, m_c=400, m_d=4000 ----------------------- pa=0x55a33ea0ced0 pb=0x55a33ea0ced0 pc=0x55a33ea0ced8 pd=0x55a33ea0ced0

本例中定義了多個對象指針,并嘗試將派生類指針賦值給基類指針。與對象變量之間的賦值不同的是,對象指針之間的賦值并沒有拷貝對象的成員,也沒有修改對象本身的數據,僅僅是改變了指針的指向。

  • 通過基類指針訪問派生類的成員
    請讀者先關注第 68 行代碼,我們將派生類指針 pd 賦值給了基類指針 pa,從運行結果可以看出,調用 display() 函數時雖然使用了派生類的成員變量,但是 display() 函數本身卻是基類的。也就是說,將派生類指針賦值給基類指針時,通過基類指針只能使用派生類的成員變量,但不能使用派生類的成員函數,這看起來有點不倫不類,究竟是為什么呢?第 71、74 行代碼也是類似的情況。

pa 本來是基類 A 的指針,現在指向了派生類 D 的對象,這使得隱式指針 this 發生了變化,也指向了 D 類的對象,所以最終在 display() 內部使用的是 D 類對象的成員變量,相信這一點不難理解。

編譯器雖然通過指針的指向來訪問成員變量,但是卻不通過指針的指向來訪問成員函數:編譯器通過指針的類型來訪問成員函數。對于 pa,它的類型是 A,不管它指向哪個對象,使用的都是 A 類的成員函數,具體原因已在《C++函數編譯原理和成員函數的實現》中做了詳細講解。

概括起來說就是:編譯器通過指針來訪問成員變量,指針指向哪個對象就使用哪個對象的數據;編譯器通過指針的類型來訪問成員函數,指針屬于哪個類的類型就使用哪個類的函數。

  • 賦值后值不一致的情況
    本例中我們將最終派生類的指針 pd 分別賦值給了基類指針 pa、pb、pc,按理說它們的值應該相等,都指向同一塊內存,但是運行結果卻有力地反駁了這種推論,只有 pa、pb、pd 三個指針的值相等,pc 的值比它們都大。也就是說,執行pc = pd;語句后,pc 和 pd 的值并不相等。
  • 將派生類引用賦值給基類引用

    引用在本質上是通過指針的方式實現的,這一點已在《引用在本質上是什么,它和指針到底有什么區別》中進行了講解,既然基類的指針可以指向派生類的對象,那么我們就有理由推斷:基類的引用也可以指向派生類的對象,并且它的表現和指針是類似的。

    修改上例中 main() 函數內部的代碼,用引用取代指針:

    int main(){D d(4, 40, 400, 4000);A &ra = d;B &rb = d;C &rc = d;ra.display();rb.display();rc.display();return 0; } Class A: m_a=4 Class B: m_a=4, m_b=40 Class C: m_c=400

    ra、rb、rc 是基類的引用,它們都引用了派生類對象 d,并調用了 display() 函數,從運行結果可以發現,雖然使用了派生類對象的成員變量,但是卻沒有使用派生類的成員函數,這和指針的表現是一樣的。

    引用和指針的表現之所以如此類似,是因為引用和指針并沒有本質上的區別,引用僅僅是對指針進行了簡單封裝,讀者可以猛擊《引用在本質上是什么,它和指針到底有什么區別》一文深入了解。

    最后需要注意的是,向上轉型后通過基類的對象、指針、引用只能訪問從基類繼承過去的成員(包括成員變量和成員函數),不能訪問派生類新增的成員。

    總結

    以上是生活随笔為你收集整理的将派生类指针赋值给基类的指针的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。