Ошибка в производном классе с использованием перегруженного оператора из базового класса - PullRequest
1 голос
/ 01 апреля 2011

Я опубликую свою проблему, а затем у меня будет код внизу.

У меня есть базовый класс (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 ]

1 голос
/ 01 апреля 2011

Это происходит потому, что 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)

То есть возвращается по значению, а не по ссылке.Это означает, что даже если у этой функции есть оператор return, который возвращает extStrSet, его часть extStrSet будет усечена.В этом случае из-за отсутствия виртуальных функций и членов-данных я считаю, что это будет работать практически на любом компиляторе, но даже при всем, что я не уверен на 100%, что это не зависит от неопределенного поведения.

0 голосов
/ 01 апреля 2011

Факт: extStrSet добавляет только пару операторов;он не добавляет и не изменяет фактический базовый набор.

Подразумевается, что в реализации операторов extStrSet следует использовать только экземпляры базового класса.operator == () определен только для extStrSet, так что вы можете оставить этот один как есть, так как внутри operator> () вы уверены, что и this, и rtSide являются (как минимум) экземплярами 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");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...