中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C++--被遺棄的多重繼承、經典問題

發布時間:2020-07-20 22:16:39 來源:網絡 閱讀:576 作者:淡淡_小孩 欄目:編程語言

一.被遺棄的多重繼承

Q:C++中是否允許一個類繼承自多個父類?
在實際的C++編譯環境中,C++是支持編寫多重繼承的代碼
1.一個子類可以擁有多個父類
2.子類擁有所有父類的成員變量
3.子類繼承所有父類的成員函數
4.子類對象可以當作任意父類對象使用
多重繼承的語法規則
C++--被遺棄的多重繼承、經典問題
但是在多重繼承中會存在許多問題
Q:多重繼承得到的對象可能擁有不同的地址
代碼示例

#include <iostream>
#include <string>

using namespace std;

class BaseA
{
    int ma;
public:
    BaseA(int a)
    {
        ma = a;
    }
    int getA()
    {
        return ma;
    }
};

class BaseB
{
    int mb;
public:
    BaseB(int b)
    {
        mb = b;
    }
    int getB()
    {
        return mb;
    }
};

class Derived : public BaseA, public BaseB//擁有兩個父類
{
    int mc;
public:
    Derived(int a, int b, int c) : BaseA(a), BaseB(b)
    {
        mc = c;
    }
    int getC()
    {
        return mc;
    }
    void print()
    {
        cout << "ma = " << getA() << ", "
             << "mb = " << getB() << ", "
             << "mc = " << mc << endl;
    }
};

int main()
{
    cout << "sizeof(Derived) = " << sizeof(Derived) << endl;   

    Derived d(1, 2, 3);

    d.print();

    cout << "d.getA() = " << d.getA() << endl;
    cout << "d.getB() = " << d.getB() << endl;
    cout << "d.getC() = " << d.getC() << endl;

    cout << endl;
    //兩個父類指針指向同一個對象
    BaseA* pa = &d;
    BaseB* pb = &d;

    cout << "pa->getA() = " << pa->getA() << endl;
    cout << "pb->getB() = " << pb->getB() << endl;

    cout << endl;

    void* paa = pa;
    void* pbb = pb;

    if( paa == pbb )
    {
        cout << "Pointer to the same object!" << endl; 
    }
    else
    {
        cout << "Error" << endl;
    }

    cout << "pa = " << pa << endl;
    cout << "pb = " << pb << endl;
    cout << "paa = " << paa << endl;
    cout << "pbb = " << pbb << endl; 

    return 0;
}

運行結果
C++--被遺棄的多重繼承、經典問題
我們可以看到在條件判斷語句中,paa與pbb指向的是同一個對象,按理說應該打印相同時的語句,可是卻打印錯誤,從接下來的地址打印結果是不一樣的,這就造成了多重繼承的問題--同一個對象取地址之后進行初始化,但是pa與pb打印的結果卻不同
C++--被遺棄的多重繼承、經典問題
Q:多重繼承可能產生冗余的成員
C++--被遺棄的多重繼承、經典問題
代碼實現

#include <iostream>
#include <string>

using namespace std;

class People
{
    string m_name;
    int m_age;
public:
    People(string name, int age)
    {
        m_name = name;
        m_age = age;
    }
    void print()
    {
        cout << "Name = " << m_name << ", "
             << "Age = " << m_age << endl;
    }
};

class Teacher : virtual public People
{
public:
    Teacher(string name, int age) : People(name, age)
    {
    }
};

class Student : virtual public People
{
public:
    Student(string name, int age) : People(name, age)
    {
    }
};

class Doctor : public Teacher, public Student
{
public:
    Doctor(string name, int age) : Teacher(name, age), Student(name, age), People(name, age)
    {
    }
};

int main()
{
    Doctor d("Delphi", 33);

    d.print();

    return 0;
}

C++--被遺棄的多重繼承、經典問題
由運行結果可以知道,在進行print時出錯,這是因為Doctor由于繼承,會有兩個打印的函數,所以通過作用域分辨符進行改正
由于冗余,打印的結果可能不一樣
C++--被遺棄的多重繼承、經典問題
當多重繼承關系出現閉合時將產生暑假冗余的問題
解決方案:虛繼承
C++--被遺棄的多重繼承、經典問題

二.經典問題分析

一.關于動態內存分配
Q:new和malloc的區別?delete和free的區別?
A.new關鍵字與malloc函數的區別
1.new關鍵字是C++的一部分,malloc是由C庫提供的函數
2.new以具體類型為單位進行內存分配,malloc以字節為單位進行內存分配
3.new在申請內存空間時可進行初始化,malloc僅根據需要申請定量的內存空間
代碼示例

#include <iostream>
#include <string>
#include <cstdlib>

using namespace std;

class Test
{
    int* mp;
public:
    Test()
    {
        cout << "Test::Test()" << endl;

        mp = new int(100);

        cout << *mp << endl;
    }
    ~Test()
    {
        delete mp;

        cout << "~Test::Test()" << endl;
    }
};

int main()
{
    Test* pn = new Test;
    Test* pm = (Test*)malloc(sizeof(Test));

    delete pn;
    free(pm);

    return 0;
}

運行結果
C++--被遺棄的多重繼承、經典問題
關于動態內存分配
new和malloc的區別
1.new在所有C++編譯器中都能被支持,malloc在某些系統開發中是不能調用的
2.new能夠觸發析構函數的調用,malloc僅分配需要的內存空間
3.對象的創建只能使用new,malloc不適合面向對象開發
delete和free的區別
1.delete在所有C++編譯器中都被支持,free在某些系統開發中是不能調用的
2.delete能夠觸發析構函數的調用,free僅歸還之前的分配空間
3.對象的銷毀只能使用delete,free不適合面向對象的開發

B.關于虛函數
Q:構造函數是否可以成為虛函數?析構函數是否可以成為虛函數?
1.構造函數不可能成為虛函數--在構造函數執行結束后,虛函數表指針才會被正確的初始化
2.析構函數可以成為虛函數--建議在設計類時將析構函數聲明為虛函數

Q:構造函數中是否可以發生多態?析構函數是否可以發生多態?
1.構造函數中不可能發生多態行為--在構造函數執行時,虛函數表指針未被正確初始化
2.析構函數在不可能發生多態行為--在析構函數執行時,虛函數表指針已經被銷毀
C.關于繼承中的強制類型轉換
1.dynamic_cast是與繼承相關的類型轉換關鍵字,并且要求相關的類中必須有虛函數
2.用于直接或者間接繼承關系的指針之間
C++--被遺棄的多重繼承、經典問題
編譯器會檢查dynamic_cast的使用是否正確,類型轉換的結果只可能在運行的階段才能得到
代碼示例

#include <iostream>
#include <string>

using namespace std;

class Base
{
public:
    Base()
    {
        cout << "Base::Base()" << endl;
    }

    virtual ~Base()//析構虛函數
    {
        cout << "Base::~Base()" << endl;
    }
};

class Derived : public Base
{

};

int main()
{
    Base* p = new Derived;//指向的是子類對象

    Derived* pd = dynamic_cast<Derived*>(p);//強制轉換

    cout<<"pd="<<pd<<endl;

    if( pd != NULL )
    {
        cout << "pd = " << pd << endl;
    }
    else
    {
        cout << "Cast error!" << endl;
    }

    delete p;

    return 0;
}

將其修改之后的打印結果比較
C++--被遺棄的多重繼承、經典問題
C++--被遺棄的多重繼承、經典問題C++--被遺棄的多重繼承、經典問題
我們可以知道不能將子類指針對象指向父類,產生的對象時無效的

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

兴城市| 阳春市| 马龙县| 枣庄市| 永修县| 阳新县| 扶绥县| 三明市| 鄯善县| 从江县| 伊金霍洛旗| 邻水| 凌海市| 榕江县| 光山县| 油尖旺区| 文登市| 竹北市| 胶州市| 同心县| 松原市| 济源市| 监利县| 余庆县| 本溪| 满洲里市| 长兴县| 嘉善县| 宁安市| 当涂县| 浮山县| 西吉县| 中方县| 长丰县| 石景山区| 高碑店市| 科技| 定日县| 嵊州市| 日土县| 永川市|