我会发布我的问题,然后我会将代码放在底部。
我有一个基类(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 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 :(得分: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");
}