operator ==如何在C ++中的类之外工作

时间:2019-01-30 01:14:35

标签: c++ class operator-overloading

我正在读CppCoreGuidelines,偶然发现了以前不知道的东西。基本上,它说我可以在类之外重载operator==,并且它将以某种方式用于比较该类的两个对象。我做到了:

#include <iostream>

class foo
{
public:
    int member;
    foo() : member(0) {}
};

bool operator==(const foo& lhs, const foo& rhs)
{
    return lhs.member == rhs.member;
}

int main()
{
    foo c1;
    foo c2;
    if (c1 == c2)
    {
        std::cout << "Even" << '\n';
    }   
}

而且,它实际上有效。因此,我开始在互联网上寻找解释。可以想象,如果我尝试比较一个对象,编译器会在此类方法中搜索operator==,这对我来说是可以理解的。但是这里我有一个函数,我猜它可以在另一个文件中定义,它完全独立于foo类(仅包含它需要的参数),但是它被认为是用于比较的一个函数。

所以现在我的问题是:编译器,或者更具体地说,我猜链接器如何找到此函数,并使用它来比较这两个对象?

1 个答案:

答案 0 :(得分:2)

假设您有一个函数bool is_equals(const foo &lhs, const foo &rhs);。编译器如何将is_equals(c1, c2)变成对is_equals的调用?

答案与operator== 完全相同。如果操作数的类型没有成员operator==,则编译器会尝试使用操作数类型查找非成员operator==。如果存在这样的东西,则将其调用;如果不存在,则将不对其进行调用。

如果您的非成员operator==重载位于另一个文件中,并且没有标头在您当前正在编译的文件中声明它,则编译器的行为如何?答案和以前一样:如果在不声明存在这样的功能的情况下调用is_equals,会发生什么?

您收到一个编译错误。该功能是否在另一个翻译单元中定义都没有关系。如果在尝试调用该函数时没有可见的声明,则会出现编译错误。

如果两个单独的文件尝试使用不同的实现来定义operator==,会发生什么?再说一次:如果您用is_equal尝试了同样的事情。您将违反C ++的“一个定义规则”,从而调用了未定义的行为。希望您会收到链接器错误,但不能保证如此。

简而言之,operator==在C ++中不是一个特殊的神奇函数。对于函数来说,这是一个不寻常的 name ,但是对于编译器或链接器来说,它并不是什么特别的东西。 special 的特殊含义是c1 == c2被转换为对operator==(c1, c2)的调用(顺便说一句,您可以编写100%合法的C ++代码,尽管它只会调用非成员operator==)。但这是关于运算符使用的特殊之处,而不是C ++函数语法。