是否重载运算符<<在班级内部工作?
我的意思是,我试图重载运算符<< 类内部,
在这样的
class A {
public:
ostream &operator<<(ostream &os);// which doesnt work
private:
friend ostream &operator<<(ostream &os, const A& a); //Works
int i;
};
Definition
ostream &operator<<(ostream &os, const A& a) {
os<<a.i;
return os;
}
为什么我不能重载特定于类的类内部的运算符?或者我错过了什么吗?或者我这么想是不是很愚蠢?请指教。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
问题是您的
operator<<
会将ostream
作为第二个参数,而不是第一个参数。这样,您就可以执行myObject << std::cout
,但它看起来不直观,并且由于operator<<
是左关联的,您将无法链接调用。将运算符声明为友元而不是成员函数的另一个好处是可以发生自动转换。这意味着,如果您有一个类
B
,它不是从A
派生的,但有一个B(A const&)
构造函数,那么您仍然能够执行 std::cout << my_b; 并将其转换为A
然后打印。幸运的是,如果您愿意,可以在类中将
operator<<
定义为友元。您的代码可以写为“为什么标准不允许您指定参数应该放在哪一边?”让我们假设它确实如此,并添加
left_of
和right_of
关键字来指定:当我们执行
A a; 时会发生什么?乙b; f(a + b);
?每个类都有一个操作符来处理这种情况,这意味着我们无法决定。无论如何,由于转换的可能性,许多操作员应该成为朋友,不允许这种事情并不是什么大问题,并且可以防止此类歧义。 (当然,您也可以定义一个成员运算符和一个自由运算符,这会导致非常相似的问题。)顺便说一句,事实上,您的
friend 运算符<<
的定义是不返回任何东西,这会弄乱链接。The problem is that your
operator<<
would takeostream
as a second parameter, not a first one. That way, you could domyObject << std::cout
, but it would look unintuitive and you would not be able to chain calls due tooperator<<
being left-associative.Another benefit of declaring the operator as a friend as opposed to a member function is that automatic conversions can occur. That means that if you have a class
B
that doesn't derive fromA
but does have aB(A const&)
constructor, you will still be able to dostd::cout << my_b;
and have it converted to anA
and then printed.Fortunately, defining
operator<<
as a friend can be done within the class if you prefer to. Your code could be written asWhy doesn't the standard allow for you to specify which side the argument should go on? Let's pretend it did, and add the
left_of
andright_of
keywords to specify:What happens now when we do
A a; B b; f(a + b);
? Each class has an operator that handles this case, which means we can't decide. Seeing as many operators should be friends due to the conversion possibilities anyway, not allowing this kind of thing is not that big a problem, and prevents these kind of ambiguities. (Of course, you could also define a member operator and a free one, which would cause a very similar problem.)By the way, as things are, the definition of your
friend operator<<
isn't returning anything, which will mess up chaining.成员函数:
确实有效,但不适合您想要的情况。当您执行以下操作时它将被调用:
即对象位于运算符的左侧。
The member function:
does work, but not for the situation you want. It will be called when you do something like:
i.e. where the object is the left-hand side of the operator.
请记住,对于类的非静态成员函数,第一个参数是 this 指针。
所以你的签名是“operator<<”函数,编译后将变成:
当您执行以下操作时,这将起作用:
将“obj”视为第一个参数,将“std::cout”视为运算符“<<”的第二个参数。
重载“<<”的更好方法是通过使用友元函数,因为通过这种方式,您可以使重载的运算符具有关联性。
Remember that for a non static member function of a class first argument is this pointer.
So the signature of your the "operator<<" function, after compilation will become:
This will work when you do something like:
Think of "obj" as first argument and "std::cout" as 2nd argument to the operator "<<".
Better way to overload "<<" is by using friend function because in this way you can make your overloaded operator associative.