C++中Covariant返回值類型詳解
前言
C++中當子類覆寫(override)父類虛函數(shù)時,子類函數(shù)的返回值類型可以和父類函數(shù)的返回值類型不一致嗎?
先說結(jié)論:可以,但當且僅當它們的返回值類型是協(xié)變返回值類型(Covariant)時可以。C++中gcc從3.4開始支持這一特性。
什么是協(xié)變返回值類型(Covariant)
函數(shù)的協(xié)變返回值類型指的是子類中的成員函數(shù)的返回值類型不必嚴格等同與該函數(shù)所重寫的父類中的函數(shù)的返回值類型,而可以是更 “狹窄” 的類型。C++/Java等面向?qū)ο缶幊陶Z言均支持協(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,因為:
- 創(chuàng)建對象時需要知道對象的完整信息
- 虛函數(shù)機制也決定了對象尚未創(chuàng)建時,類的virtual table或許還不存在
- 我們不可能有指向virtual constructor的指針
但是我們可以通過上面的代碼實現(xiàn)類似的想法,如果我們擁有指向?qū)ο蟮闹羔槪?/strong>
- 通過clone()調(diào)用對象的拷貝構(gòu)造函數(shù),復制當前的對象
- 通過create()調(diào)用默認構(gòu)造函數(shù),創(chuàng)建新的對象
比如下面的使用場景:
void userCode(Shape* s)
{
Shape* s2 = s->clone();
Shape* s3 = s->create();
// ...
delete s2;
delete s3;
}如果指針指向的是基類對象,調(diào)用上述函數(shù)時返回的就是指向基類對象的指針并賦值給s2/s3,如果指針指向的是子類對象,調(diào)用上述函數(shù)時返回的就是指向子類對象的指針并賦值給s2/s3。
協(xié)變返回值類型(Covariant)的作用
協(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:
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分支來判斷s是指向子類Circle還是指向基類Shape,失去了動態(tài)綁定的意義。
到此這篇關于C++中Covariant返回值類型詳解的文章就介紹到這了,更多相關C++ Covariant內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
淺析C++中dynamic_cast和static_cast實例語法詳解
這篇文章主要介紹了淺析C++中dynamic_cast和static_cast實例演示,包括static_cast語法知識和static_cast的作用講解,namic_cast 語法詳解,需要的朋友可以參考下2021-07-07
C++實現(xiàn)LeetCode(557.翻轉(zhuǎn)字符串中的單詞之三)
這篇文章主要介紹了C++實現(xiàn)LeetCode(557.翻轉(zhuǎn)字符串中的單詞之三),本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下2021-08-08
C語言數(shù)據(jù)結(jié)構(gòu)中數(shù)制轉(zhuǎn)換實例代碼
這篇文章主要介紹了C語言數(shù)據(jù)結(jié)構(gòu)中數(shù)制轉(zhuǎn)換實例代碼的相關資料,需要的朋友可以參考下2017-03-03

