C++ 繼承詳解及實(shí)例代碼
C++繼承可以是單一繼承或多重繼承,每一個(gè)繼承連接可以是public,protected,private也可以是virtual或non-virtual。然后是各個(gè)成員函數(shù)選項(xiàng)可以是virtual或non-virtual或pure virtual。本文僅僅作出一些關(guān)鍵點(diǎn)的驗(yàn)證。
public繼承,例如下:
1 class base
2 {...}
3 class derived:public base
4 {...}
如果這樣寫,編譯器會(huì)理解成類型為derived的對(duì)象同時(shí)也是類型為base的對(duì)象,但類型為base的對(duì)象不是類型為derived的對(duì)象。這點(diǎn)很重要。那么函數(shù)形參為base類型適用于derived,形參為derived不適用于base。下面是驗(yàn)證代碼,一個(gè)參數(shù)為base的函數(shù),傳入derived應(yīng)該成功執(zhí)行,相反,一個(gè)參數(shù)為derived的函數(shù)
#include <iostream> #include <stdio.h> class base { public: base() :baseName(""),baseData(0) {} base(std::string bn,int bd) :baseName(bn),baseData(bd) {} std::string getBaseName() const { return baseName; } int getBaseData()const { return baseData; } private: std::string baseName; int baseData; }; class derived:public base { public: derived():base(),derivedName("") {} derived(std::string bn,int bd,std::string dn) :base(bn,bd),derivedName(dn) {} std::string getDerivedName() const { return derivedName; } private: std::string derivedName; }; void show(std::string& info,const base& b) { info.append("Name is "); info.append(b.getBaseName()); info.append(", baseData is "); char buffer[10]; sprintf(buffer,"%d",b.getBaseData()); info.append(buffer); } int main(int argc,char* argv[]) { base b("test",10); std::string s; show(s,b); std::cout<<s<<std::endl; derived d("btest",5,"dtest"); std::string ss; show(ss,d); std::cout<<ss<<std::endl; return 0; }
運(yùn)行結(jié)果為:
base:baseName is test, baseData is 10
base:baseName is btest, baseData is 5
下面改改代碼,將函數(shù)參數(shù)變?yōu)閐erived
void show2(std::string& info,const derived& d) { info.append("Name is "); info.append(d.getBaseName()); info.append(", baseData is "); char buffer[10]; sprintf(buffer,"%d",d.getBaseData()); info.append(buffer); }
調(diào)用show(ss,d);編譯器報(bào)錯(cuò)
1 derived_class.cpp: In function `int main(int, char**)': 2 derived_class.cpp:84: error: invalid initialization of reference of type 'const derived&' from expression of type 'base' 3 derived_class.cpp:70: error: in passing argument 2 of `void show2(std::string&, const derived&)'
第二點(diǎn)對(duì)各種形式的繼承作出驗(yàn)證,首先給出表格
繼承方式\成員類型 | public | protected | private |
public | public | protected | 無(wú)法繼承 |
protected | protected | protected | 無(wú)法繼承 |
private | private | private | 無(wú)法繼承 |
這里解釋一下,這里僅僅表達(dá)基類的成員,被public,protected,private三種方式繼承后,在原基類為public,protectedc,private的成員在繼承類里類型為表格里內(nèi)容
class base { public: std::string testPublic() { return std::string("this is public base"); } protected: std::string testProtected() { return std::string("this is protected base"); } private: std::string testPrivate() { return std::string("this is private base"); } }; class derivedPublic:public base { public: std::string testPubPublic() { return testPublic()+= "in derived"; } std::string testProPublic() { return testProtected()+= "in derived"; } std::string testPriPublic() { return testPrivate()+= "in derived"; } }; int main(int argc,char* argv[]) { derivedPublic dpub; std::cout << dpub.testPublic() << std::endl; }
報(bào)下面錯(cuò)誤,說(shuō)明testPrivate()不是derived私有函數(shù)而是base的私有函數(shù)
derived11.cpp:16: error: `std::string base::testPrivate()' is private derived11.cpp:36: error: within this context
這樣驗(yàn)證private類型成員無(wú)法被繼承(public,private,protected)注:private,protected略去不做證明
下面只要驗(yàn)證 testProtected 能被第三層繼承類繼承,但是無(wú)法被第三層類直接調(diào)用就說(shuō)明是public繼承后繼承類型為protected,而基類為Public類型成員則即可被繼承又可以直接調(diào)用。
#include <iostream> #include <string> class base { public: std::string testPublic() { return std::string("this is public base"); } protected: std::string testProtected() { return std::string("this is protected base"); } private: std::string testPrivate() { return std::string("this is private base"); } }; class derivedPublic:public base { public: std::string testPubPublic() { return testPublic()+= "in derived"; } std::string testProPublic() { return testProtected()+= "in derived"; } // std::string testPriPublic() // { // return testPrivate()+= "in derived"; // } }; class deepDerived:public derivedPublic { public: std::string deepProtected() { return testProtected() +="in deep"; } std::string deepPublic() { return testPublic() +="indeep"; } }; int main(int argc,char* argv[]) { derivedPublic dpub; std::cout << dpub.testProtected() << std::endl; deepDerived deepdpub; std::cout<<deepdpub.testPublic() <<std::endl; std::cout<<deepdpub.testProtected() <<std::endl; std::cout<<deepdpub.deepProtected() <<std::endl; std::cout<<deepdpub.deepPublic() <<std::endl; }
這里服務(wù)器報(bào)錯(cuò)
derived12.cpp:13: error: `std::string base::testProtected()' is protected derived12.cpp:62: error: within this context
這樣就驗(yàn)證了一個(gè)是public,一個(gè)是protected,protected是不能直接調(diào)用的,但是被繼承后是可以被public成員調(diào)用的。
下面的已經(jīng)證明,詳細(xì)步驟就略去如果對(duì)該部分驗(yàn)證感興趣,可以看下面代碼。
#include <iostream> #include <string> class base { public: std::string testPublic() { return std::string("this is public base"); } protected: std::string testProtected() { return std::string("this is protected base"); } private: std::string testPrivate() { return std::string("this is private base"); } }; class derivedPublic:public base { public: std::string testPubPublic() { return testPublic()+= "in derived"; } std::string testProPublic() { return testProtected()+= "in derived"; } // std::string testPriPublic() //私有成員并沒(méi)有被繼承下來(lái) // { // return testPrivate()+= "in derived"; // } }; class deepDerived:public derivedPublic { public: std::string test() { return testPublic() +="in 3"; } }; class derivedProtected:protected base { public: std::string testPubProtected() { return testPublic()+= "in derived"; } std::string testProProtected() { return testProtected()+= "in derived"; } }; class deepDerived2:public derivedProtected { public: std::string test() { return testPublic() +="in 3"; } }; class derivedPrivate:private base { public: std::string testPubPirvate() { return testPublic()+= "in derived"; } std::string testProPrivate() { return testProtected()+= "in derived"; } }; //class deepDerived3:public derivedPrivate //{ // public: // std::string test() // { // return testPublic() +="in 3"; // } //}; int main(int argc,char* argv[]) { derivedPublic dpub; //derivedProtected dpro; //derivedPrivate dpri; std::cout<<dpub.testPublic()<<std::endl; // //std::cout<<dpub.testProtected()<<std::endl; //用戶被繼承也是無(wú)法使用 //cout<<dpub.testPrivate()<<std::endl; //基類都是私有函數(shù) std::cout<<dpub.testPubPublic()<<std::endl; std::cout<<dpub.testProPublic()<<std::endl; //std::cout<<dpub.testPriPrivate()<<std::endl; //沒(méi)有被繼承 deepDerived dd; std::cout<<dd.test()<<std::endl; derivedProtected dpro; //std::cout<<dpro.testPublic()<<std::endl; //變成protected類型 std::cout<<dpro.testPubProtected()<<std::endl; std::cout<<dpro.testProProtected()<<std::endl; deepDerived2 dd2; std::cout<<dd2.test()<<std::endl; derivedPrivate dpri; std::cout<<dpri.testPubPirvate()<<std::endl; std::cout<<dpri.testProPrivate()<<std::endl; // deepDerived3 dd3; // std::cout<<dd3.test()<<std::endl; }
以上就是對(duì)C++ j繼承的資料整理,后續(xù)繼續(xù)補(bǔ)充相關(guān)資料,謝謝大家對(duì)本站的支持!
相關(guān)文章
C++實(shí)現(xiàn)將簡(jiǎn)單密碼譯回原文的方法
這篇文章主要介紹了C++實(shí)現(xiàn)將簡(jiǎn)單密碼譯回原文的方法,可實(shí)現(xiàn)將簡(jiǎn)單的字母位移類型的密碼譯回原文的功能,涉及C++簡(jiǎn)單字符串操作相關(guān)技巧,需要的朋友可以參考下2016-05-05C++string底層框架模擬實(shí)現(xiàn)代碼
本節(jié)文章主要說(shuō)明淺拷貝和深拷貝的優(yōu)缺點(diǎn),以及仿寫string類的邏輯并分析實(shí)現(xiàn)過(guò)程,對(duì)C++string底層框架模擬實(shí)現(xiàn)代碼感興趣的朋友一起看看吧2021-11-11利用C++實(shí)現(xiàn)計(jì)算機(jī)輔助教學(xué)系統(tǒng)
我們都知道計(jì)算機(jī)在教育中起的作用越來(lái)越大。這篇文章主要為大家詳細(xì)介紹了如何利用C++編寫一個(gè)計(jì)算機(jī)輔助教學(xué)系統(tǒng),感興趣的可以了解一下2023-05-05關(guān)于C/C++中typedef的定義與用法總結(jié)
在C還是C++代碼中,typedef都使用的很多,在C代碼中尤其是多,typedef與#define有些相似,其實(shí)是不同的,特別是在一些復(fù)雜的用法上,需要的朋友可以參考下2012-12-12