2011-04-01 45 views
1

我將發佈我的問題,然後我將底部的代碼。使用來自基類的重載運算符的派生類的錯誤

我有一個基類(strSet),它重載了+, - ,*,=運算符。
我已經派生類(extStrSet)已經過載<,>,==運營商

在派生類重載「<」和「>」操作符的執行情況,我必須使用的「* '操作員(來自基類)。

但我收到一個錯誤,我真的不知道爲什麼會發生。這些錯誤這樣說:

extstrset3.cpp: In member function âextStrSet extStrSet::operator>(const extStrSet&)â: 

extstrset3.cpp:17: error: no match for âoperator=â in âtemp = strSet::operator*(const strSet&)(((const strSet&)(&((const extStrSet*)rtSide)->extStrSet::<anonymous>)))â 

extstrset3.h:11: note: candidates are: extStrSet& extStrSet::operator=(const extStrSet&) 
extstrset3.cpp: In member function âextStrSet extStrSet::operator<(const extStrSet&)â: 

extstrset3.cpp:29: error: no match for âoperator=â in âtemp = strSet::operator*(const strSet&)(((const strSet&)(&((const extStrSet*)rtSide)->extStrSet::<anonymous>)))â 

extstrset3.h:11: note: candidates are: extStrSet& extStrSet::operator=(const extStrSet&) 

extstrset3.cpp:35: error: ânewSetâ was not declared in this scope 

extstrset3.cpp: In member function âextStrSet extStrSet::operator==(const extStrSet&)â: 

extstrset3.cpp:41: error: no match for âoperator=â in âtemp = strSet::operator*(const strSet&)(((const strSet&)(&((const extStrSet*)rtSide)->extStrSet::<anonymous>)))â 

extstrset3.h:11: note: candidates are: extStrSet& extStrSet::operator=(const extStrSet&) 

extstrset3.cpp:45: error: ânewSetâ was not declared in this scope 

注:我不會改變任何兩個頭文件。
注意:我知道一個事實,即strSet.h和strSet.cpp正確實現。
注:重載「==」運算符返回一個extStrSet(串集)與「真」或「假」作爲其唯一的字符串

我應該能夠使用*操作上extStrSet即使它爲strSet重載,不應該嗎?我只是開始繼承,所以我仍然有點謹慎。

strSet.h

#ifndef STRSET_H 
#define STRSET_H 

#include <iostream> 
#include <vector> 
#include <string> 

struct node { 
    std::string s1; 
    node * next; 
}; 

class strSet { 

protected: 
    node * first; 
     // This is initially empty (when constructed) 
    bool isSorted() const; 

public: 
    strSet(); // Create empty set 
    strSet (std::string s); // Create singleton set 
    strSet (const strSet &copy); // Copy constructor 
    ~strSet(); // Destructor 

    void nullify(); // Make a set be empty 
    bool isNull() const; 
    int SIZE() const; 

    void output() const; 

    bool isMember (std::string s) const; 

    strSet operator + (const strSet& rtSide); // Union 
    strSet operator * (const strSet& rtSide); // Intersection 
    strSet operator - (const strSet& rtSide); // Set subtraction 
    strSet& operator = (const strSet& rtSide); // Assignment 


}; // End of strSet class 

#endif 

extStrSet.h

#ifndef EXTSTRSET_H 
#define EXTSTRSET_H 

#include <string> 
#include "strset3.h" 

class extStrSet : public strSet 
{ 
public: 
    extStrSet operator == (const extStrSet& rtSide); // Equal 
    extStrSet operator < (const extStrSet& rtSide); // Strict subset 
    extStrSet operator > (const extStrSet& rtSide); // Strict superset 
    // Leave off other comparisons: != <= >= 

    extStrSet (); 
    extStrSet (std::string s); 
}; 

inline extStrSet& ss2extss (const strSet& ss) // Downcast 
    { return *(extStrSet*)&ss ; } 

#endif 

extStrSet.cpp

#include <iostream> 
#include <vector> 
#include <string> 
#include "extstrset3.h" 
#include "strset3.h" 

using namespace std; 

extStrSet::extStrSet() : strSet() {} 

extStrSet::extStrSet(string s) : strSet(s) {} 

extStrSet extStrSet::operator > (const extStrSet& rtSide) { 
    extStrSet temp; 
    extStrSet temp2; 
    extStrSet newSet; 
    temp = *this * rtSide; 
    temp2 = *this == rtSide; 
    if(temp2.isMember("true")) extStrSet newSet("false"); 
    else if(rtSide.SIZE() == temp.SIZE()) extStrSet newSet("true"); 
    else extStrSet newSet("false"); 
    return newSet; 
} 

extStrSet extStrSet::operator < (const extStrSet& rtSide) { 
    extStrSet temp; 
    extStrSet temp2; 
    temp = *this * rtSide; 
    temp2 = *this == rtSide; 
    if(temp2.isMember("true")) extStrSet newSet("false"); 
    else if(SIZE() == temp.SIZE()) extStrSet newSet("true"); 
    else extStrSet newSet("false"); 
    return newSet; 

} 

extStrSet extStrSet::operator == (const extStrSet& rtSide) { 
    extStrSet temp; 
    temp = *this * rtSide; 
    if(SIZE() == rtSide.SIZE() && SIZE() == temp.SIZE()) extStrSet newSet("true"); 
    else extStrSet newSet("false"); 
    return newSet; 
} 
+0

它有助於做temp = this-> operator *(rtSide); – highBandWidth 2011-04-01 04:11:42

+0

不,我試過了,收到了同樣的錯誤。 – Tesla 2011-04-01 04:19:46

+0

難道是運算符*需要返回strSet&或const strSet&? – highBandWidth 2011-04-01 04:24:18

回答

1

這是發生因爲strSet :: operator *()返回一個strSet而不是一個extStrSet。要清楚這個表達式

*this * rtSide; 

返回一個strSet。這部分

extStrSet temp = 

期望給予一個extStrSet,但它給了一個strSet。您有此功能

inline extStrSet& ss2extss (const strSet& ss) // Downcast 
{ return *(extStrSet*)&ss ; } 

對於從strSet轉換爲extStrSet。我認爲,在這種情況下,你可以做

temp = ss2extss(*this * rtSide); 

但要注意的是,這只是工作,因爲在這些類沒有虛函數和extStrSet不添加任何數據成員。困難是因爲*運算符被定義爲

strSet operator*(strSet &rhs) 

這是按值返回而不是通過引用。這意味着即使該函數具有返回extStrSet的返回語句,它的extStrSet部分也會被截斷。在這種情況下,由於缺少虛擬函數和數據成員,我相信這對幾乎所有的編譯器都有效,但即使我不能100%確信這不依賴於未定義的行爲。

0

事實:extStrSet只添加了幾個操作符;它不會添加任何或更改實際的基礎集。

暗示我認爲你應該在extStrSet操作符的實現中只使用基類的實例。 operator ==()只是爲extStrSet定義的,所以你可以保持原樣,因爲在operator>()內部,你確定'this'和'rtSide'是(至少)extStrSet的實例。 h。

HTH, h。

extStrSet extStrSet::operator > (const extStrSet& rtSide) { 
    strSet temp; 
    extStrSet temp2; 
    // explicitly call baseclass operator* 
    temp = (this->strSet::operator*)(rtSide); 
    temp2 = (*this == rtSide); 
    if(temp2.isMember("true")) 
     return extStrSet("false"); 
    else if(rtSide.SIZE() == temp.SIZE()) 
     return extStrSet("true"); 
    else 
     return extStrSet("false"); 
}