C++ 何时使用内部操作员,何时使用外部操作员

C++ 何时使用内部操作员,何时使用外部操作员,c++,C++,假设我定义了一个类,它有一个内部的+操作符和一个外部的+操作符 class MyClass { public: MyClass operator +(); }; MyClass operator +(const MyClass& a); 如果在我的主程序中,我调用 MyClass a; MyClass b = +a; 被称为什么,这(内部): 还是这个(外部)?: 对于二进制运算符,同样的问题。通过修复代码中的一些歧义,并进行一些打印,下面的代码将给出答案内

假设我定义了一个类,它有一个内部的
+
操作符和一个外部的
+
操作符

class MyClass {
    public:
        MyClass operator +();
};

MyClass operator +(const MyClass& a);
如果在我的主程序中,我调用

MyClass a;
MyClass b = +a;
被称为什么,这(内部):

还是这个(外部)?:


对于二进制运算符,同样的问题。

通过修复代码中的一些歧义,并进行一些打印,下面的代码将给出答案
内部运算符

class MyClass {
public:
    MyClass operator+() {
        std::cout << "Internal operator." << std::endl;
        return *this;
    };
};

MyClass operator+(const MyClass& a) {
    std::cout << "External operator" << std::endl;
    return a;
}

int main() {
    MyClass a, b;
    b = +a;
    return 0;
}
class-MyClass{
公众:
MyClass运算符+(){

std::cout之所以使用内部运算符,是因为一旦运算符已经存在,就不能用相同的参数重载该运算符:不能为执行某些疯狂操作的字符串定义+运算符,因为已经有一个运算符将它们串联在一起。这是同一情况。您在类中定义了+运算符,因此相同的运算符(作为功能原型)变得无用。

选择了成员函数:它可以直接绑定到表达式
a
,而非成员函数需要在绑定到引用参数之前将
MyClass
转换为
const MyClass
。因此,调用成员涉及更好的转换顺序,这是最好的重载


如果您从非成员中删除了
const
,或将
const
添加到成员中,则两者都是同样可行的;您应该会得到一个错误,说明重载不明确。

我自己做了一个小测试:

#include <iostream>
#include "MyClass.h"

using namespace std;

MyClass operator +(const MyClass& a, const MyClass& b)
{ cout << "external" << endl; return a; }

int main() {
    MyClass foo, bar;
    foo + bar;
    return 0;
}

class MyClass {
public:
    MyClass operator+(const MyClass& a) { cout << "internal" << endl; return a; }
};
#包括
#包括“MyClass.h”
使用名称空间std;
MyClass运算符+(常量MyClass&a、常量MyClass&b)

{cout您是否尝试过
std::cout同意(然而,目的只是显示调用了哪个函数,而不是实际使用答案。)。解释为什么使用内部运算符而不是外部运算符,以及为什么使用外部运算符而不是内部运算符,这将是非常棒的。我可以很容易地打印出结果并得出相同的结论,但有趣的是给出了一个原因。@dabadaba:看到我的答案了。其中一个涉及到转换n到
const
,一个没有,这会使它成为更好的重载。我如何才能将
const
添加到成员中?你的意思是它应该返回一个
const MyClass
以与外部操作符相等吗?@dabadaba:通常的方式:
MyClass操作符+()const;
噢,好的,一个常量方法。在这种情况下,使用的是外部方法。很有趣。但是我得到了您指出的警告。如果我从外部运算符的参数中删除
const
,我会得到一个错误而不是警告。但是如果我将成员运算符声明为const,则会使用外部运算符。我不明白。@d阿巴达巴:如果我同时声明两者(或两者都不声明)作为
const
,我得到一个错误,因为它是不明确的:。如果从非成员中删除
const
,并将其添加到成员中,那么非成员将成为更好的重载,因为它不再需要转换,而成员现在需要。不,您可以同时声明成员候选项和非成员候选项,并且可以选择其中一个取决于操作数类型。(这通常是个坏主意,但不是你不能做的事情)。但我谈论的是原型(返回类型、名称和参数)相同的情况。然后,非成员候选对象是无用的,因为它从未被调用。但这里不是这样。它们有不同的参数类型(
MyClass
vs.
const MyClass
),因此可以根据操作数类型选择其中任何一种。如果它们相同,则重载将不明确,从而产生错误。对不起,我没有看到它。通常运算符+方法声明为const,我想我已经习惯了这样的情况。
class MyClass {
public:
    MyClass operator+() {
        std::cout << "Internal operator." << std::endl;
        return *this;
    };
};

MyClass operator+(const MyClass& a) {
    std::cout << "External operator" << std::endl;
    return a;
}

int main() {
    MyClass a, b;
    b = +a;
    return 0;
}
#include <iostream>
#include "MyClass.h"

using namespace std;

MyClass operator +(const MyClass& a, const MyClass& b)
{ cout << "external" << endl; return a; }

int main() {
    MyClass foo, bar;
    foo + bar;
    return 0;
}

class MyClass {
public:
    MyClass operator+(const MyClass& a) { cout << "internal" << endl; return a; }
};