c++ public 函数名相同_C++虚函数、重载、覆盖
C++基礎(五)虛函數、重載、覆蓋、隱藏 虛函數總是跟多態聯系在一起,引入虛函數可以使用基類指針對繼承類對象進行操作!虛函數:繼承接口(函數名,參數,返回值),但是實現不繼承(函數體)
非虛函數:繼承接口,也繼承實現;
1)虛析構函數(當一個類打算作為基類使用時候,其析構函數必須是虛函數)
構造函數可以為虛函數嗎? 不可以,在生成對象的時候,必須向編譯器明確指定要生成什么類型的對象,因而不存在虛函數的問題;只有當對象已經存在,我用什么接口去操作它的問題;
例子:
class A{public:A();virtual~A();};class B: public A{public: B();~B();};int main(){A *pA=new B; //調用B的構造函數delete pA; return 0; }
這里通過指針A去調用B類的析構函數,但是如果 ~A()不是虛析構函數,就不存在多態,就會去調用A中的析構函數,最后結果可能是B對象中的A成分被析構了,其他 還殘留;所以當一個類作為基類時候,其析構函數必須是虛函數,這樣防止出現析構不完全的情況;
2)當虛函數出現在構造、析構函數中時(即在構造函數中調用虛函數),函數退化為普通函數。為什么? <>中條款
例子:(轉自<>中條例9)
class Transaction
{public:Transaction();virtual void LogTransaction() const = 0;// ...};Transaction::Transaction(){// ...LogTransaction();}class BuyTransaction : public Transaction
{public:virtual void LogTransaction() const;// ...};
這里調用BuyTransaction的構造函數,因為BuyTransaction是繼承類所以先調用基類的構造函數,此時派生類獨有的那部分還未初始化,<>中這么解釋:“這個對象內的BuyTransaction成分還未初始化,最安全的辦法是當他不存在,對象在derived成分還未初 始化時該對象不會成為一個derived對象”所以Transaction 的構造函數會調用基類的 LogTransaction() const;而且此處是個純虛函數,會報錯
3)虛函數與覆蓋,重載,隱藏
重載首先出現在非繼承關系當中,當同一個類中,兩個函數的參數不同,名字相同,返回值類型無所謂(函數返回值不作為重載的參考,因為函數調用時候不出現返回值);
注意兩個函數可以僅僅因為const與非const的差別來實現重載;
虛函數與覆蓋均出現在一個繼承體系中,覆蓋針對的是普通函數,當父類子類中出現同名(相同返回值,相同參數,相同函數名)要求絕對一致;
虛函數在父類子類中,首先在父類中聲明該函數為virtual,那么子類可以重新定義該函數的實現,這里主要涉及多態,就是覆蓋的情況加上virtual,通過指針或者引用實現多態;
隱藏顯得簡單粗暴,在繼承類中只要出現于父類同名(只要求同樣的函數名/變量名,其他返回值,virtual 非virtual不管)的函數,則用對象調用同名函數時候,基類對應的同名函數、變量隱藏,如果要訪問其父類的同名成員應該明確使用 基類名::成員來訪問;
例子:
class A{public:virtual ~A(){};void process(int i,char c); //重載,編譯期間即可確定該調用哪個函數char process(double d,int c); //只要函數名相同,返回無所謂,參數不同void process(int i); void process(int i)const; // 此處相當于void process(const A *this,int i);void process(consttint i); //這里僅僅因為const屬性不同即可實現重載virtual int foo(int, char){...}; int foo2(){};void foo3(int,int ){};}class B: public A{public:int foo(int ,char){...}; //虛函數,這里函數接口要嚴格一致(大部分編譯器要求返回值也要一致)int process(){...}; //隱藏基類函數 int foo2(){}; // 這里不含虛屬性,會覆蓋int foo3(){return 0;}; //會隱藏A類的foo3}int main(){B b;A *pA=&b;pA->foo2(); //這里調用A類的foo2();不涉及多態;pA->foo(3,'c'); //B類foo() 涉及多態}
總結:
1)覆蓋與虛函數是一對兄弟,要求函數的返回值,函數名,參數嚴格一致,虛函數是覆蓋加上virtual的情況;
2) 隱藏是覆蓋的推廣,覆蓋是隱藏的特例,只要求函數名一樣,其他不管,在繼承體系中,子類的同名函數會將父類的同名函數隱藏;
3)當使用指針時候,指向基類的指針會根據實際對象的類型,選擇相應的虛函數執行,如果派生類沒有重新定義基類的虛函數,那么依然執行基類的虛函數;
4)當不存在虛函數的情況下,使用基類的指針,不會下降到派生類中去搜索函數;所以virtual屬性相當于告訴基類指針:當執行我時,請到相應對象中搜索對應的虛函數;
5)純虛函數所在的類是抽象類,不能實例化,定義了純虛函數意味著這個函數只能為父類,其負責定義接口而不負責實現;
6)當使用對象來調用相應的函數時候,主要考慮的是對基類同名函數的隱藏(包括覆蓋),而不需要考慮多態;
7)注意構造析構函數中不能調用虛函數,當執行派生類的構造函數時候,先構造的是其基類成分,再執行派生類成分的構造,虛函數此時無意義;
8)c++是個細節非常多,非常復雜的語言。
更多內容,歡迎關注我的公眾號:無情劍客
新人創作打卡挑戰賽發博客就能抽獎!定制產品紅包拿不停!總結
以上是生活随笔為你收集整理的c++ public 函数名相同_C++虚函数、重载、覆盖的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: oracle用户登录报错,oracle用
- 下一篇: php 伪造请求连接,phpcurl发送