Q:C++中是否允許一個類繼承自多個父類?
在實(shí)際的C++編譯環(huán)境中,C++是支持編寫多重繼承的代碼
1.一個子類可以擁有多個父類
2.子類擁有所有父類的成員變量
3.子類繼承所有父類的成員函數(shù)
4.子類對象可以當(dāng)作任意父類對象使用
多重繼承的語法規(guī)則
但是在多重繼承中會存在許多問題
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;
}
運(yùn)行結(jié)果
我們可以看到在條件判斷語句中,paa與pbb指向的是同一個對象,按理說應(yīng)該打印相同時的語句,可是卻打印錯誤,從接下來的地址打印結(jié)果是不一樣的,這就造成了多重繼承的問題--同一個對象取地址之后進(jìn)行初始化,但是pa與pb打印的結(jié)果卻不同
Q:多重繼承可能產(chǎn)生冗余的成員
代碼實(shí)現(xiàn)
#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;
}
由運(yùn)行結(jié)果可以知道,在進(jìn)行print時出錯,這是因?yàn)镈octor由于繼承,會有兩個打印的函數(shù),所以通過作用域分辨符進(jìn)行改正
由于冗余,打印的結(jié)果可能不一樣
當(dāng)多重繼承關(guān)系出現(xiàn)閉合時將產(chǎn)生暑假冗余的問題
解決方案:虛繼承
一.關(guān)于動態(tài)內(nèi)存分配
Q:new和malloc的區(qū)別?delete和free的區(qū)別?
A.new關(guān)鍵字與malloc函數(shù)的區(qū)別
1.new關(guān)鍵字是C++的一部分,malloc是由C庫提供的函數(shù)
2.new以具體類型為單位進(jìn)行內(nèi)存分配,malloc以字節(jié)為單位進(jìn)行內(nèi)存分配
3.new在申請內(nèi)存空間時可進(jìn)行初始化,malloc僅根據(jù)需要申請定量的內(nèi)存空間
代碼示例
#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;
}
運(yùn)行結(jié)果
關(guān)于動態(tài)內(nèi)存分配
new和malloc的區(qū)別
1.new在所有C++編譯器中都能被支持,malloc在某些系統(tǒng)開發(fā)中是不能調(diào)用的
2.new能夠觸發(fā)析構(gòu)函數(shù)的調(diào)用,malloc僅分配需要的內(nèi)存空間
3.對象的創(chuàng)建只能使用new,malloc不適合面向?qū)ο箝_發(fā)
delete和free的區(qū)別
1.delete在所有C++編譯器中都被支持,free在某些系統(tǒng)開發(fā)中是不能調(diào)用的
2.delete能夠觸發(fā)析構(gòu)函數(shù)的調(diào)用,free僅歸還之前的分配空間
3.對象的銷毀只能使用delete,free不適合面向?qū)ο蟮拈_發(fā)
B.關(guān)于虛函數(shù)
Q:構(gòu)造函數(shù)是否可以成為虛函數(shù)?析構(gòu)函數(shù)是否可以成為虛函數(shù)?
1.構(gòu)造函數(shù)不可能成為虛函數(shù)--在構(gòu)造函數(shù)執(zhí)行結(jié)束后,虛函數(shù)表指針才會被正確的初始化
2.析構(gòu)函數(shù)可以成為虛函數(shù)--建議在設(shè)計(jì)類時將析構(gòu)函數(shù)聲明為虛函數(shù)
Q:構(gòu)造函數(shù)中是否可以發(fā)生多態(tài)?析構(gòu)函數(shù)是否可以發(fā)生多態(tài)?
1.構(gòu)造函數(shù)中不可能發(fā)生多態(tài)行為--在構(gòu)造函數(shù)執(zhí)行時,虛函數(shù)表指針未被正確初始化
2.析構(gòu)函數(shù)在不可能發(fā)生多態(tài)行為--在析構(gòu)函數(shù)執(zhí)行時,虛函數(shù)表指針已經(jīng)被銷毀
C.關(guān)于繼承中的強(qiáng)制類型轉(zhuǎn)換
1.dynamic_cast是與繼承相關(guān)的類型轉(zhuǎn)換關(guān)鍵字,并且要求相關(guān)的類中必須有虛函數(shù)
2.用于直接或者間接繼承關(guān)系的指針之間
編譯器會檢查dynamic_cast的使用是否正確,類型轉(zhuǎn)換的結(jié)果只可能在運(yùn)行的階段才能得到
代碼示例
#include <iostream>
#include <string>
using namespace std;
class Base
{
public:
Base()
{
cout << "Base::Base()" << endl;
}
virtual ~Base()//析構(gòu)虛函數(shù)
{
cout << "Base::~Base()" << endl;
}
};
class Derived : public Base
{
};
int main()
{
Base* p = new Derived;//指向的是子類對象
Derived* pd = dynamic_cast<Derived*>(p);//強(qiáng)制轉(zhuǎn)換
cout<<"pd="<<pd<<endl;
if( pd != NULL )
{
cout << "pd = " << pd << endl;
}
else
{
cout << "Cast error!" << endl;
}
delete p;
return 0;
}
將其修改之后的打印結(jié)果比較
我們可以知道不能將子類指針對象指向父類,產(chǎn)生的對象時無效的
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點(diǎn)與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。
網(wǎng)站標(biāo)題:C++--被遺棄的多重繼承、經(jīng)典問題-創(chuàng)新互聯(lián)
分享網(wǎng)址:http://aaarwkj.com/article18/jdedp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供搜索引擎優(yōu)化、網(wǎng)站制作、小程序開發(fā)、商城網(wǎng)站、企業(yè)建站、Google
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)