使用operator ==和!=比较C ++中的不同类

时间:2015-11-30 05:34:51

标签: c++

我试图比较C ++中不同类的对象。 如果我删除section3,一切都很顺利。但我想知道如何编辑比较运算符==!=以使其无任何错误地运行? 我得到的错误是"no match for 'operator==' (operand types are 'Fruit' and 'Plant') "

这是我的代码:

#include <iostream>
#include <string>
class Plant
{
public:
    Plant(std::string name) : type_(name)
    { }

    bool operator==(const Plant &that) const
    { return type_ == that.type_; }

    bool operator!=(const Plant &that) const
    { return !operator==(that); }

    void print()
    { std::cout << type_ << std::endl; }

protected:
    std::string type_;
};

class Fruit: public Plant
{
public:
    Fruit(std::string name, std::string taste)
        : Plant(name)
        , taste_(taste)
    { }

    bool operator==(const Fruit& that) const
    {
        return ( (taste_ == that.taste_) && (Plant::operator==(that)) );
    }

    bool operator!=(const Fruit& that) const
    {
        return !operator==(that);
    }

    void print()
    {
        Plant::print();
        std::cout << taste_ << std::endl;
    }

private:
    std::string taste_;
};


int main()
{
    Plant a("Maple");
    a.print();
    Plant b("Maple");

    if (a == b)
    {
        std::cout << "a and b are equal" << std::endl;
    }
    else
    {
        std::cout << "a and b are not equal" << std::endl;
    }

    Fruit c("Apple","sweet");
    c.print();
    Fruit d("Apple","sweet");

    if (c == d)
    {
        std::cout << "c and d are equal" << std::endl;
    }
    else
    {
        std::cout << "c and d are not equal" << std::endl;
    }

    if (a == c)
    {
        std::cout << "a and c are equal" << std::endl;
    }
    else
    {
        std::cout << "a and c are not equal" << std::endl;
    }

    /* Section 3 */
    if (c == a)
    { std::cout <<"c and a are equal\n"<< std::endl; }
    else
    { std::cout <<"c and a are not equal\n"<< std::endl; }

    if (a != c)
    { std::cout <<"c and a are not equal\n"<< std::endl; }
    else
    { std::cout <<"c and a are equal\n"<< std::endl; }
    return 0;
}

谢谢..

3 个答案:

答案 0 :(得分:1)

您必须实施比较器操作员来比较水果和植物,或者将水果向下植物比较:

bool operator==(const Plant& plant, const Fruit& fruit) { /* test here */ }
bool operator==(const Fruit& fruit, const Plant& plant) { return (plant == fruit); }

或者如果你有指针:

Fruit* fruit = new Fruit("apple", "sour");
Plant* plant = new Plant("maple"); 
if(*plant == *static_cast<Plant*>(fruit)) {}

答案 1 :(得分:1)

您可以添加非会员功能

bool operator==(Fruit const& f, Plant const& p)
{
   return false;
}

bool operator!=(Fruit const& f, Plant const& p)
{
   return !(f == p);
}

这适用于Plant的一个子类型。这种方法不可扩展。如果您创建了更多Plant的子类型,则需要使用其他方法。

答案 2 :(得分:1)

有点不清楚你想要实现什么,但显然它涉及动态类型检查,如果两个对象动态地具有一些共同基类型X并且相等,则它们相等根据该基类型中指定的一些标准。

查找公共类型X通常是一个棘手的问题,因为C ++支持多重继承。但是,如果假设为了简单起见,单继承,也就是说,每个类最多只有一个基类,那么可以让其中一个参与比较的对象走了基类链并使用例如dynamic_cast检查其他对象是否属于此类型,例如像这样:

#include <string>
#include <utility>      // std::move

using Byte_string = std::string;

class Base
{
private:
    Byte_string s_;

protected:
    virtual
    auto equals( Base const& other ) const
        -> bool
    { return s_ == other.s_; }

public:
    friend
    auto operator==( Base const& a, Base const& b )
        -> bool
    { return a.equals( b ); }

    explicit Base( Byte_string s )
        : s_( move( s ) )
    {}
};

class Derived
    : public Base
{
private:
    Byte_string t_;

protected:
    auto equals( Base const& other ) const
        -> bool override
    {
        if( auto p_other = dynamic_cast<Derived const*>( &other ) )
        {
            return Base::equals( other ) and t_ == p_other->t_;
        }
        return Base::equals( other );
    }

public:
    Derived( Byte_string s, Byte_string t )
        : Base( move( s ) )
        , t_( move( t ) )
    {}
};

class Most_derived
    : public Derived
{
private:
    int u_;

protected:
    auto equals( Base const& other ) const
        -> bool override
    {
        if( auto p_other = dynamic_cast<Most_derived const*>( &other ) )
        {
            return Derived::equals( other ) and u_ == p_other->u_;
        }
        return Derived::equals( other );
    }

    Most_derived( Byte_string s, Byte_string t, int u )
        : Derived( move( s ), move( t ) )
        , u_( u )
    {}

};

#include <iostream>
using namespace std;
auto main() -> int
{
    Base a( "Maple" );
    Base b( "Maple" );
    cout << "a and b are " << (a == b? "" : "not ") << "equal.\n";

    Derived c( "Apple", "sweet" );
    Derived d( "Apple", "sweet" );
    cout << "c and d are " << (c == d? "" : "not ") << "equal.\n";

    cout << "a and c are " << (a == c? "" : "not ") << "equal.\n";
    cout << "c and a are " << (c == a? "" : "not ") << "equal.\n";

    Base& x = d;
    cout << "x and c are " << (x == c? "" : "not ") << "equal.\n";
    cout << "c and x are " << (c == x? "" : "not ") << "equal.\n";

}