2013-07-09 55 views
0

我有一個基類容器類,它有一些運算符(=,+, - ,+ =等)。預計操作符的邏輯不需要爲派生類改變。因此,理想情況下,我想爲所有派生類使用基類運算符,而不必爲每個派生類顯式重新定義它們(除賦值運算符外)。派生類的操作符重載

基於一個簡單的例子,下面演示了我提出的解決方案。該解決方案似乎有效,但我對該方法對於更復雜案例的有效性抱有懷疑。你認爲在B班使用這個作業「黑客」是否有效?這種方法的潛在缺陷是什麼?有什麼我錯過了嗎?是否有更簡單的方法來實現我需要的功能(即對派生類使用基類運算符)?

class A 
{ 
protected: 
int a; 
public: 
A(int ca) 
{ 
    a=ca; 
} 
A(const A& A1) 
{ 
    a=A1.a; 
} 

int geta() const 
{ 
    return a; 
} 
void seta(int ca) 
{ 
    a=ca; 
} 
const A& operator=(const A& A1) 
{ 
    a=A1.a; 
    return *this; 
} 

}; 

const A operator+(const A& A1, const A& A2) 
{ 
A myA(A1.geta()+A2.geta()); 
return myA; 
} 

class B: public A 
{ 
public: 
B(int a): A(a) {}// ... using A::A; 
const B& operator=(const B& B1) 
{ 
    a=B1.geta(); 
    return *this; 
} 
const B& operator=(const A& B1) 
{ 
    a=B1.geta(); 
    return *this; 
} 

}; 

int main() 
{ 

B myB(4); 
A myA(3); 

//need this to work 
myB=myB+myB; 
cout << myB.geta(); 
myA=myA+myA; 
cout << myA.geta(); 

int j; 
cin >> j; 

}

+0

在這段代碼中,B沒有任何可見的用途,僅僅是一個沒有添加內容的A的薄包裝。這就是爲什麼'myB = myB + myB'的原因。如果你的真實代碼是這樣的,那麼就去除B。如果真實的B比A更容易達到,那麼你應該怎麼處理它。 –

+0

@ n.m。你是對的。我現在意識到這個例子並不代表真正的問題。我將不得不重新提交問題。感謝您的評論。 – user1391279

+0

@ user1391279您好,我只是想提一提,[最近刪除的問題(http://webcache.googleusercontent.com/search?q=cache:AmeqkRXnNHYJ:stackoverflow.com/questions/26790845/passing-ublas-subrange-一個函數+&cd = 1&hl = en&ct = clnk&gl = br&client = firefox-a)導致了這個非常有趣的討論:http://stackoverflow.com/q/26793072/1000282。我會回答,但是,正如你所看到的,現在它已經被刪除了。對不起,但我想不出有什麼其他聯繫方式,我希望在閱讀之前,這個評論不會被適度刪除。 –

回答

0

對於給定的我沒有看到可能發生的任何問題的例子。因爲你可以改進代碼,首先通過在operator =中返回非const引用,其次我認爲通過將+ = op加入你的類,並在全局運算符+函數中使用它的代碼。

但總的來說,我認爲它應該可以正常工作。至於賦值操作符 - 只要你只有POD類型,沒有指針,或引用或句柄,你就不需要任何操作。 然而,當指針出現時,它會變得更加複雜。你需要確保你複製對象,指向他們,或者以其他方式管理它們。

而且你可能不需要,只要你不添加更多成員派生類,這也應該參與計算,以修改您的運營商。

0

一般來說,你不必重新定義基類函數派生類。通過公共繼承,派生類將可以訪問這些函數並使用它們的操作。如果你想重新定義它們(例如=運算符),確保你調用了正確的(在這種情況下,虛擬函數有幫助)。