2012-06-08 105 views
2

我有幾個共享公共基類的類,但它們的方法工作方式不同。所以在下面的例子中,除了執行計算的方式之外,Adder和Multiplier是相同的。將對象從一個派生類更改爲另一個派生類

有沒有辦法來改變「A」到事半功倍的對飛?我是否需要實現將派生類相互轉換的方法?例如像

a = a.asMultiplier()

正如你可以在代碼中看到下面我試圖reinterpret_cast的乘法器,沒有運氣,但它仍然就像一個加法器。 (GCC OS X V4.2.1)

#include <iostream> 


class Base { 
protected: 
    int a,b;  
public: 
    Base(int a, int b) { 
     this->a = a; 
     this->b = b; 
    } 
    virtual ~Base() { }  
    virtual int calculate() = 0; 
}; 


class Adder : public Base {  
public: 
    Adder(int a, int b) : Base(a, b) { 

    }  
    int calculate() { 
     return this->a + this->b; 
    } 
}; 


class Multiplier : public Base {  
public: 
    Multiplier(int a, int b) : Base(a, b) {  
    } 

    int calculate() { 
     return this->a * this->b; 
    } 
}; 



int main() { 

    Base* a = new Adder(3,4); 
    Base* m = new Multiplier(3,4); 

    std::cout << "Adder gives " << a->calculate() << std::endl; 
    std::cout << "Multiplier gives " << m->calculate() << std::endl; 

    a = reinterpret_cast<Multiplier*>(a); 

    std::cout << "Now adder gives " << a->calculate() << std::endl; 

    delete a; 
    delete m; 
    return 0; 
} 
+6

嘗試將一個派生對象轉換爲另一個派生對象的想法很好地表明您的設計需要重新審視。 –

+0

偏離主題,但我總是被告知,如果在C++中不需要它,則不應該使用「this」。但這只是我猜想的慣例問題。 –

+0

我認爲這是一個抽象的例子,但除非你有會員資料,爲什麼還要打擾呢?當需要我想象時,簡單地創建一個新的「乘數」就更加透明。在你開始投射的那一刻,你爲自己和其他需要與你的代碼進行交互的人制造更復雜的事情 – sji

回答

5

,來了最好的事情,給我解決這個問題,正在實施一個拷貝構造函數,以基類:

class Multiplier : public Base {  
public: 
    Multiplier(int a, int b) : Base(a, b) {  
    } 

    explicit Multiplier(const Base& iBase) : Base(iBase.a, iBase.b) {  
    } 

    int calculate() { 
     return this->a * this->b; 
    } 
}; 

但是自從我在這裏是不是最先進的C++開發者,它可能不正確或其他人可能有更好的想法,只是想:)

+0

至少使這個轉換構造函數'explicit',否則你會邀請微妙的錯誤 – sehe

+0

@sehe,完全正確!糾正。 –

4

我會建議其業務分離對象的數據。通過這種方式,您可以輕鬆地構造另一個對象,從而超越數據。所以,你的「轉換」將是這樣的:Multiplier m = new Multiplier(a);

做它,你所要求的是不可能在C++的方式。

3

這對我來說似乎需要對數據進行操作的實用類:將您的基類更改爲Data類,其目的僅僅是存儲數據並將數據明確傳遞給Adder,Multiplier等類。

,您仍然可以使用繼承的實用工具類,如果它上面的重構後是有道理的:在這種情況下,基地也將一個數據對象進行操作的而不是數據本身

2

改變你的設計可能是一個好主意。一般來說,當基類和派生類共享某種共同性時,不僅在數據方面,而且在行爲方面,使用繼承是一個好主意。雖然不是非常有用的建議,但我建議讀一些關於面向對象設計原理的書。試圖以你真實的方式投射類型是沒有意義的。

+1

我的理解,並與其他一些答覆和意見的結合,我可以看到從行爲中分離數據的優勢。我給出的例子非常基本。實際上,我使用的類做分享兩個數據共性和行爲與基類的一個很大。這只是一個是依賴於對象(例如加法器或乘法器)的特定的「類型」方法屈指可數。 我原先wen't下該路徑,因爲我的印象是,檢查在運行時類的類型是派生類應替代地使用的指示。 –

相關問題