2012-01-10 65 views
0

我想要做的東西像下面這樣:子對象作爲參數

virtual void Aircraft::getImage(GenericImage&)=0; 
void Drone::getImage(Image&); 

其中 ImageGenericImage Drone一個子類是Aircraft一個子類。

我該如何要求無人機類有一個getImage(any subclass of genericImage&)方法沒有編譯器抱怨genericImageImage不是一回事?我希望最終用戶/ dev能夠使用他們自己的圖像格式來定義他們自己的無人機類,它們擴展了genericImage,但無論他們創建了什麼,他們都必須提供從無人機獲取圖像的功能。

回答

1

不要帶出參數,只需返回圖像。返回類型允許爲covariant。這意味着,只要Image居然公開從GenericImage派生,這將是罰款:

virtual GenericImage& Aircraft::getImage() = 0; 
virtual Image& Drone::getImage(); 
+0

謝謝。這正是我正在尋找的。 – imjojo42 2012-01-11 00:05:07

+0

@user:問題是,爲什麼你真的想在派生的飛機上使用派生圖像?爲什麼不只是在那裏返回'GenericImage'呢? – Xeo 2012-01-11 00:19:57

+0

背後的原因是因爲每架飛機都有不同的圖像格式。因此,每架飛機都將擁有與該飛機相同的不同格式,但所有飛機都會有圖像。 – imjojo42 2012-01-11 00:27:56

0

這是不可能改變的參數這樣,也不應該是因爲它一般會違反里氏替換原則(LSP ):根據定義,Aircraft::getImage可接受任何GenericImage,其包括GenericImage的任意子類。子類必須符合該接口,因此也必須接受任何GenericImage。但是,您明確要指定它只接受特定的子類型Image

注意,這種情況是返回類型不同,因爲這些代表事物的功能產生的而不是事物的功能接受(你會說你getImage還生產,但C++不知道這個概念的輸出參數,並且確實必須將現有對象傳遞給getImage才能將其填充圖像數據)。因爲對於返回類型,轉到派生類型不違反LSP,C++的確允許它(該特性稱爲協變返回類型)。因此,解決方案是在函數內部分配圖像對象並返回(最好使用指針 - 一個智能指針,不幸的是不能用於協變返回類型 - 指示發生的分配)。也就是說,你的函數會讀

class Aircraft 
{ 
    virtual GenericImage* getImage() = 0; 
}; 

class Drone: public Aircraft 
{ 
    virtual Image* getImate() { return new Image(); } 
}; 

但是很有可能你會只使用基類的接口,無論如何,所以我寧願只是在界面中GenericImage去,而是利用智能指針:

class Aircraft 
{ 
    virtual std::unique_ptr<GenericImage> getImage() = 0; 
}; 

class Drone: public Aircraft 
{ 
    virtual std::unique_ptr<GenericImage> getImate() { return new Image(); } 
};