C++中Covariant返回值類型詳解
前言
C++中當(dāng)子類覆寫(override)父類虛函數(shù)時(shí),子類函數(shù)的返回值類型可以和父類函數(shù)的返回值類型不一致嗎?
先說(shuō)結(jié)論:可以,但當(dāng)且僅當(dāng)它們的返回值類型是協(xié)變返回值類型(Covariant)時(shí)可以。C++中g(shù)cc從3.4開始支持這一特性。
什么是協(xié)變返回值類型(Covariant)
函數(shù)的協(xié)變返回值類型指的是子類中的成員函數(shù)的返回值類型不必嚴(yán)格等同與該函數(shù)所重寫的父類中的函數(shù)的返回值類型,而可以是更 “狹窄” 的類型。C++/Java等面向?qū)ο缶幊陶Z(yǔ)言均支持協(xié)變返回值類型。
例子:
class Shape { public: virtual ~Shape() { } virtual Shape* clone() const = 0; // Uses the copy constructor virtual Shape* create() const = 0; // Uses the default constructor }; class Circle : public Shape { public: Circle* clone() const; // Covariant Return Types; see below Circle* create() const; // Covariant Return Types; see below }; Circle* Circle::clone() const { return new Circle(*this); } Circle* Circle::create() const { return new Circle(); }
C++中不支持virtual constructor,因?yàn)椋?/strong>
- 創(chuàng)建對(duì)象時(shí)需要知道對(duì)象的完整信息
- 虛函數(shù)機(jī)制也決定了對(duì)象尚未創(chuàng)建時(shí),類的virtual table或許還不存在
- 我們不可能有指向virtual constructor的指針
但是我們可以通過上面的代碼實(shí)現(xiàn)類似的想法,如果我們擁有指向?qū)ο蟮闹羔槪?/strong>
- 通過clone()調(diào)用對(duì)象的拷貝構(gòu)造函數(shù),復(fù)制當(dāng)前的對(duì)象
- 通過create()調(diào)用默認(rèn)構(gòu)造函數(shù),創(chuàng)建新的對(duì)象
比如下面的使用場(chǎng)景:
void userCode(Shape* s) { Shape* s2 = s->clone(); Shape* s3 = s->create(); // ... delete s2; delete s3; }
如果指針指向的是基類對(duì)象,調(diào)用上述函數(shù)時(shí)返回的就是指向基類對(duì)象的指針并賦值給s2/s3,如果指針指向的是子類對(duì)象,調(diào)用上述函數(shù)時(shí)返回的就是指向子類對(duì)象的指針并賦值給s2/s3。
協(xié)變返回值類型(Covariant)的作用
協(xié)變返回類型到底有什么用呢,編譯器為什么要支持這種語(yǔ)法?如果編譯器不支持,上面的例子將只能寫成如下這樣:
class Shape { public: virtual ~Shape() { } virtual Shape* clone() const = 0; // Uses the copy constructor virtual Shape* create() const = 0; // Uses the default constructor }; class Circle : public Shape { public: Shape* clone() const; // Covariant Return Types; see below Shape* create() const; // Covariant Return Types; see below }; Shape* Circle::clone() const { return new Circle(*this); } Shape* Circle::create() const { return new Circle(); }
這樣上面的userCode函數(shù)將不能通過編譯,上面調(diào)用clone函數(shù)部分將不得不改寫成下面這樣:
void userCode(Shape* s) { Shape* s2 = s->clone(); Circle* c = dynamic_cast<Circle*>(s2); if (c != NULL) { // c point to Circle } else { if (s2 != NULL) { // s2 point to base Shape } } } // ... delete s2; }
通過if/else分支來(lái)判斷s是指向子類Circle還是指向基類Shape,失去了動(dòng)態(tài)綁定的意義。
到此這篇關(guān)于C++中Covariant返回值類型詳解的文章就介紹到這了,更多相關(guān)C++ Covariant內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C/C++編程判斷String字符串是否包含某個(gè)字符串實(shí)現(xiàn)示例
這篇文章主要為大家介紹了C++編程中判斷String字符串是否包含某個(gè)字符串的實(shí)現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-11-11C/C++ ip地址與int類型的轉(zhuǎn)換實(shí)例詳解
這篇文章主要介紹了C/C++ ip地址與int類型的轉(zhuǎn)換實(shí)例詳解的相關(guān)資料,這里提供了實(shí)例代碼,實(shí)現(xiàn)思路及實(shí)現(xiàn)方法,需要的朋友可以參考下2016-12-12C++中使用function和bind綁定類成員函數(shù)的方法詳解
這篇文章主要介紹了C++中使用function和bind綁定類成員函數(shù)的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11C語(yǔ)言實(shí)現(xiàn)的程序員老黃歷實(shí)例
這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)的程序員老黃歷,涉及日期的判定及流程控制的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-07-07