【问题标题】:How do I call a child's overloaded operator from a function in the parent class which has a reference to the parent as a parameter?如何从以父类为参数的父类中的函数调用子类的重载运算符?
【发布时间】:2017-02-02 03:31:10
【问题描述】:

如何在一个类中获得一个重载的关系运算符,以便从父类中的函数调用,该函数将基类的 const 引用作为参数传递给该函数?以下代码演示了我想做的事情:

class Object 
{
public:
    virtual ~Object(void);
    virtual int compare(Object const& obj) const;
};

int Object::compare(Object const & obj) const {
    if(this == &obj)
    {
        return 0;
    }
    else if(this < &obj)
    {
        return -1;
    } else{
        return 1;
    }
}

class Integer: public Object
{
private:
    int myInt;
public:
    Integer(int i);
    bool operator==(const Integer& integer);
};

bool Integer::operator==(Integer const &integer) {
    if(myInt == integer.myInt)
    {
        return true;
    }
    return false;
}

如何让基类中的比较函数调用子类中的 == 运算符,记住我还有其他子类?

我尝试过 dynamic_cast,但由于某种原因它不起作用。

【问题讨论】:

  • 请注意,您只是比较地址而不是基类中的对象。

标签: c++ inheritance polymorphism operator-overloading


【解决方案1】:

我愿意:

#include <iostream>

class Object 
{
public:
    virtual ~Object(void) {};
    int compare(Object const& obj) const;
    virtual bool operator==(Object const& integer) const = 0;
    virtual bool operator<(Object const& integer) const = 0;
    virtual bool operator>(Object const& integer) const = 0;
};

int Object::compare(Object const& obj) const
{
    if(*this == obj)
        return 0;
    else if(*this < obj)
        return -1;
    else return 1;
}

class Integer: public Object
{
private:
    int myInt;
public:
    Integer(int i) : myInt(i) { };
    virtual bool operator==(Object const& integer) const override;
    virtual bool operator<(Object const& integer) const override;
    virtual bool operator>(Object const& integer) const override;
};

bool Integer::operator==(Object const& integer) const
{
    return myInt == dynamic_cast<Integer const&>(integer).myInt;
}

bool Integer::operator<(Object const& integer) const
{
    return myInt < dynamic_cast<Integer const&>(integer).myInt;
}

bool Integer::operator>(Object const& integer) const
{
    return myInt > dynamic_cast<Integer const&>(integer).myInt;
}
int main()
{
    Integer a(2), b(2), c(3);
    std::cout << a.compare(b) << std::endl;
    std::cout << b.compare(c) << std::endl;
    std::cout << c.compare(a) << std::endl;
}

但实际上你应该只在继承类中提供虚拟compare 函数,如下所示:

class Object 
{
public:
    virtual ~Object(void) {};
    virtual int compare(Object const& obj) const = 0;
};

class Integer: public Object
{
private:
    int myInt;
public:
    Integer(int i) : myInt(i) { };
    virtual int compare(Object const& object) const override;
    bool operator==(Integer const& integer) const;
    bool operator<(Integer const& integer) const;
    bool operator>(Integer const& integer) const;
};

int Integer::compare(Object const& object) const
{
    Integer const& ref = dynamic_cast<Integer const&>(object);
    if(ref == *this)
        return 0;
    else if(ref > *this)
        return 1;
    else return -1;
}

bool Integer::operator==(Integer const& integer) const
{
    return myInt == integer.myInt;
}

bool Integer::operator<(Integer const& integer) const
{
    return myInt > integer.myInt;
}

bool Integer::operator>(Integer const& integer) const
{
    return myInt < integer.myInt;
}

【讨论】:

  • 我得到一个错误,说如果我使用 *this == obj 则无法比较结构
【解决方案2】:

您可以添加另一个虚拟方法isEqual 来连接Integer::operator==

唯一的要求是将Object::isEqual 签名保留在Integer 类中。您还应该记住,您的 Object::compare 方法可以(意外地)在不同类型的对象上调用。

class Object 
{
protected:
    virtual bool isEqual(Object const& obj) const
      { return this == &obj; }
public:
    virtual ~Object(void);
    virtual int compare(Object const& obj) const;
};

int Object::compare(Object const & obj) const {
    if(isEqual(obj))
    {
        return 0;
    }
    else if(this < &obj)
    {
        return -1;
    } else{
        return 1;
    }
}

class Integer: public Object
{
private:
    int myInt;
protected:
    virtual bool isEqual(Object const& obj) const
      { if (!dynamic_cast<const Integer*>(&obj))
          return false;
        return *this == (const Integer&) obj;
      }
public:
    Integer(int i);
    bool operator==(const Integer& integer);
};

【讨论】:

  • 谢谢,成功了。现在,如果我想为另一个子类提供相同的功能,我只需在另一个子类中实现 isEqual?
  • @Keagansed 是的,它应该可以工作。您也可以覆盖子类中的方法 compare 以直接调用operator==isEqual 返回 false 时的默认指针比较可能是错误的或至少难以调试(在非调试模式下不可重现)。
  • 非常感谢您的帮助。我所做的与您所说的差不多。我在子类中覆盖了 compare 以测试是否可以进行动态转换,如果不是,我返回了 Object::compare(obj) ,它只是比较了我的地址这样做它至少有一个默认操作,如果可能的话,我直接调用 operator== 就像你在 isEqual 中所做的那样。我会赞成你的回答,但我没有足够的声誉这样做..再次感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-29
  • 2022-06-13
  • 1970-01-01
  • 2014-08-03
  • 2019-05-10
相关资源
最近更新 更多