2010-05-19 85 views
4

這裏是我的問題代碼:C++重載虛擬=操作


class ICommon 
{ 
public: 
virtual ICommon& operator=(const ICommon & p)const=0; 
}; 

class CSpecial : public ICommon 
{ 
public: 
CSpecial& operator=(const CSpecial & cs)const 
{ 
    //custom operations 
    return *this; 
} 
}; 
CSpecial obj; 

基本上是:我希望接口ICommon迫使它的後代實現=操作,但不希望在執行任何類型轉換。編譯器說,「不能實例化一個抽象類。
任何幫助/建議將不勝感激。

+1

你想實現什麼?你想讓所有的擴展類在最派生的層次上使用自己的類型來實現'operator =',或者你想實現一個可以通過引用使用的多態'operator =' /指向基礎接口? – 2010-05-19 07:51:58

+1

與David一樣,我不確定你想達到什麼目的。希望確保派生類編寫器生成自己的複製賦值運算符(從而防止編譯器生成隱式賦值運算符),編寫抽象虛擬運算符將不起作用,因爲即使編寫者在派生類中實現了這一點(必須使用ICommon& operator =(const ICommon&)),編譯器仍然會隱式生成ISpecial&operator =(ISpecial&)。 – 2010-05-19 08:08:30

回答

2

爲了迴應Naveen所說的,CSpecial中定義的operator=()與ICommon中定義的不兼容,導致過載而不是一個覆蓋。雖然你可以有協變返回類型(如你所做的那樣),但參數本身不能協變。

此外,您已將ICommon::operator=()定義爲const,這似乎違反直覺。在派生類中,您已將它設置爲非const(如預期的那樣),但同樣,這會使函數簽名進一步不兼容。

Naveen的clone()想法可能是你最好的選擇。否則,你可以將一個ICommon常量引用傳遞給你的CSpecial operator=(),並在內部嘗試一些dynamic_cast<>()魔法,但這很有趣。

祝你好運!

+0

感謝您的解釋。 – taz 2010-05-19 05:02:03

3

這是因爲功能的CSpecial簽名是你在抽象基類中定義的純虛函數不同你可以使用virtual copy constructor來進行復制,基本上你可以在基類中定義一個純虛函數ICommon* clone() = 0,並在每個派生類中實現它,當調用這個函數時,它將創建一個被調用對象的副本

+0

感謝您的選擇。 – taz 2010-05-19 05:01:10

1

您可以使用遞歸模板來實現你想要的:

template<typename T> 
struct IAssignable { 
    virtual T& operator =(const T&) = 0; 
}; 

struct Impl : IAssignable<Impl> { 
    virtual Impl& operator =(const Impl&) { return *this; } 
}; 

這不,不能,用來強制拷貝構造函數中實現。所以我不相信這是非常有用的,而你可能更喜歡clone()其他人建議的選項。但它是一個有用的結構。

0

基本上是:我希望接口 ICommon迫使它的後代 落實=操作,但不希望 必須在 執行任何類型轉換。 。編譯器說 「不能實例化一個抽象類 任何幫助/建議將理解

考慮將基類的公有接口從它的(虛擬)操作實現:

class ICommon 
{ 
public: 
    ICommon& operator=(const ICommon & p) 
    { 
     if(this == &p) 
      return *this; 
     copy(p); 
     return *this; 
    } 
protected: 
    virtual void copy(const ICommon& p) = 0; 
}; 

class CSpecial : public ICommon 
{ 
protected: 
    virtual void copy(const ICommon& p) 
    { 
     // TODO: copy values from p 
    } 
};