使用基类中的重载运算符时出现派生类错误

发布于 2024-10-28 02:33:46 字数 4739 浏览 1 评论 0原文

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

我有一个基类 (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;
}

I'll post my issue and then I'll have the code at the bottom.

I have a base class (strSet) that has overloaded +,-,*,= operators.
I have a derived class (extStrSet) that has overloaded <,>,== operators

In the implementation of the overloaded '<' and '>' operators in the derived class, i have to use the '*' operator (from the base class).

But I am getting an error that I'm really not sure why is happening. The errors say this:

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

NOTE: I am not to change either of the two header files.
NOTE: I know for a fact that strSet.h and strSet.cpp are implemented correctly.
NOTE: The overloaded '==' operator returns a extStrSet (string set) with "true" or "false" as its only string

I should be able to use the * operator on extStrSet even though its overloaded for strSet, shouldn't I? I'm just starting inheritance so I'm still a bit wary of it.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一笔一画续写前缘 2024-11-04 02:33:46

发生这种情况是因为 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% 确信这不依赖于未定义的行为。

This is happening because the strSet::operator*() returns a strSet not an extStrSet. To be clear this expression

*this * rtSide; 

returns a strSet. This part

extStrSet temp =

expects to be given an extStrSet, but it is given a strSet. You have this function

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

For converting from strSet to extStrSet. I believe that in this case you can do

temp = ss2extss(*this * rtSide);

but it is important to note that this only works, because there are no virtual functions in these classes and extStrSet does not add any data members. The difficulty is because the * operator is defined as

strSet operator*(strSet &rhs)

That is return by value not by reference. That means that even if that function has a return statement that returns an extStrSet, the extStrSet part of it will be truncated. In this case because of the lack of virtual functions and data members I believe this will work on just about any compiler, but even with all that I am not 100% confident that this does not rely on undefined behavior.

猥琐帝 2024-11-04 02:33:46

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

言下之意,我认为在 extStrSet 运算符的实现中,您应该仅使用基类的实例。 operator==() 仅为 extStrSet 定义,因此您可以按原样保留该操作符,因为在 operator>() 内部,您确定“this”和“rtSide”(至少)都是 extStrSet 的实例。

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

Fact: the extStrSet only adds a couple of operators; it doesn't add any or change the actual underlying set.

By implication I think you should, in the implementation of the extStrSet operators, only use instances of the baseclass. operator==() is only defined for extStrSet so you can leave that one as-is, since inside operator>() you're sure that both 'this' and 'rtSide' are (at least) instances of extStrSet.

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");
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文