Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么对操作员而言,朋友函数比成员函数更受欢迎<&书信电报;_C++_Operator Overloading - Fatal编程技术网

C++ 为什么对操作员而言,朋友函数比成员函数更受欢迎<&书信电报;

C++ 为什么对操作员而言,朋友函数比成员函数更受欢迎<&书信电报;,c++,operator-overloading,C++,Operator Overloading,当您要打印对象时,友元运算符您必须使用自由函数而不是成员函数。对于二进制运算符,左侧始终是*对于成员函数,右侧作为另一个参数传递 对于输出流操作符,左侧始终是流对象,因此,如果要流到标准类,而不是自己编写流,则必须提供一个自由函数,而不是类的成员 虽然可以提供一个向后流操作符作为成员函数,并按如下方式输出: myObject >> std::cout; 正如您所指出的,您不仅会违反非常强大的库约定,而且由于从左到右分组>,所以链接输出操作将不起作用 编辑:正如其他人所指出的,虽然您

当您要打印对象时,友元运算符您必须使用自由函数而不是成员函数。对于二进制运算符,左侧始终是
*对于成员函数,右侧作为另一个参数传递

对于输出流操作符,左侧始终是流对象,因此,如果要流到标准类,而不是自己编写流,则必须提供一个自由函数,而不是类的成员

虽然可以提供一个向后流操作符作为成员函数,并按如下方式输出:

myObject >> std::cout;
正如您所指出的,您不仅会违反非常强大的库约定,而且由于从左到右分组
>
,所以链接输出操作将不起作用

编辑:正如其他人所指出的,虽然您必须使其成为一个自由函数,但如果流媒体功能无法在类的公共界面中实现,则它只需要是一个
朋友。

您别无选择,它必须是一个自由函数

但是,请注意,它不一定是一个
friend
函数。它只需要是一个朋友,如果你真的需要授予它私人访问权。例如,我在编程竞赛中使用以下内容:

template <class A, class B>
std::ostream& operator<<(std::ostream& os, const std::pair<A, B>& p)
{
  return os << '(' << p.first << ", " << p.second << ')';
}
模板

std::ostream&operator在您的示例中还有一个原因-它必须是
朋友
,因为这是在类定义中定义自由函数的唯一方法。如果您想要一个非好友自由函数,那么它必须在类之外定义

为什么您希望在类中定义它?有时,最好将所有运算符一起定义:

struct SomeClass {
    // blah blah blah
    SomeClass &operator+=(const SomeClass &rhs) {
        // do something
    }
    friend SomeClass operator+(SomeClass lhs, const SomeClass &rhs) {
        lhs += rhs;
        return lhs;
    }
    // blah blah blah
    // several pages later
};
可能比以下内容更便于用户使用:

struct SomeClass {
    // blah blah blah
    SomeClass &operator+=(const SomeClass &rhs) {
        // do something
    }
    // blah blah blah
    // several pages later
};

SomeClass operator+(SomeClass lhs, const SomeClass &rhs) {
    lhs += rhs;
    return lhs;
}
当然,这假设您是在类定义中定义相关的成员函数,而不是在那里声明它们并在.cpp文件中定义它们


编辑:我使用+=和+作为示例,但没有认真考虑,但您的问题是关于
运算符您不能。但是如果你不想让它成为朋友函数,就让它成为一个自由函数,并根据类的公共接口实现它。例如

 ostream& operator<<(ostream& os, Myclass& obj)
{
   return obj.print(os);
}

ostream& MyClass::print(ostream& os)
{
   os << val; // for example.
   return os;
}

ostream&operator您真的还需要其他原因吗?@mmyers:我只是尽可能清楚地理解它……它显然不能是成员函数(参见Charles Bailey的答案),但它不一定是朋友-如果您能从类的公共接口实现它,那太好了。你在问题中回答了。它不能是成员函数,因为如果是,您必须编写
a
struct SomeClass {
    // blah blah blah
    SomeClass &operator+=(const SomeClass &rhs) {
        // do something
    }
    // blah blah blah
    // several pages later
};

SomeClass operator+(SomeClass lhs, const SomeClass &rhs) {
    lhs += rhs;
    return lhs;
}
 ostream& operator<<(ostream& os, Myclass& obj)
{
   return obj.print(os);
}

ostream& MyClass::print(ostream& os)
{
   os << val; // for example.
   return os;
}