派生类使用基类重载运算符时出错

时间:2011-04-01 03:58:53

标签: c++ class operator-overloading

我会发布我的问题,然后我会将代码放在底部。

我有一个基类(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(字符串集),其中包含“true”或“false”作为唯一的字符串

我应该可以在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;
}

2 个答案:

答案 0 :(得分: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的return语句,它的extStrSet部分也将被截断。在这种情况下,由于缺少虚函数和数据成员,我相信这将适用于任何编译器,但即便如此,我也不能100%确信这不依赖于未定义的行为。

答案 1 :(得分:0)

事实:extStrSet只添加了几个运算符;它不会添加任何或更改实际的基础集。

通过暗示我认为你应该在extStrSet运算符的实现中只使用基类的实例。 operator ==()仅为extStrSet定义,因此你可以保留原来的那个,因为在运算符&gt;()中你确定这两个&#39;这个&#39;和&#39; rtSide&#39;是(至少)extStrSet的实例。

HTH, 小时。

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");
}