是否重载运算符<<在班级内部工作?

发布于 2025-01-07 01:34:50 字数 518 浏览 3 评论 0 原文

我的意思是,我试图重载运算符<< 类内部,

在这样的

 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;
          }

为什么我不能重载特定于类的类内部的运算符?或者我错过了什么吗?或者我这么想是不是很愚蠢?请指教。

I mean, I was trying to overload the operator<< inside the class

like this

 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;
          }

why can't I overload the operator inside the class specific to class? or Am I missing something? or Am I stupid to even think in such a way? Please advise.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

颜漓半夏 2025-01-14 01:34:50

问题是您的 operator<< 会将 ostream 作为第二个参数,而不是第一个参数。这样,您就可以执行 myObject << std::cout,但它看起来不直观,并且由于 operator<< 是左关联的,您将无法链接调用。

将运算符声明为友元而不是成员函数的另一个好处是可以发生自动转换。这意味着,如果您有一个类 B,它不是从 A 派生的,但有一个 B(A const&) 构造函数,那么您仍然能够执行 std::cout << my_b; 并将其转换为 A 然后打印。

幸运的是,如果您愿意,可以在类中将 operator<< 定义为友元。您的代码可以写为“

class A {
    int i;
    friend std::ostream& operator<<(std::ostream& o, A const& a) {
        o << a.i;
        return o;
    }
};

为什么标准不允许您指定参数应该放在哪一边?”让我们假设它确实如此,并添加 left_ofright_of 关键字来指定:

struct B;

struct A {
     A left_of operator+(B const&) {
         return *this;
     }
};

struct B {
     B right_of operator+(A const&) {
         return *this;
     }
};

当我们执行 A a; 时会发生什么?乙b; f(a + b);?每个类都有一个操作符来处理这种情况,这意味着我们无法决定。无论如何,由于转换的可能性,许多操作员应该成为朋友,不允许这种事情并不是什么大问题,并且可以防止此类歧义。 (当然,您也可以定义一个成员运算符和一个自由运算符,这会导致非常相似的问题。)

顺便说一句,事实上,您的 friend 运算符<< 的定义是不返回任何东西,这会弄乱链接。

The problem is that your operator<< would take ostream as a second parameter, not a first one. That way, you could do myObject << std::cout, but it would look unintuitive and you would not be able to chain calls due to operator<< 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 from A but does have a B(A const&) constructor, you will still be able to do std::cout << my_b; and have it converted to an A and then printed.

Fortunately, defining operator<< as a friend can be done within the class if you prefer to. Your code could be written as

class A {
    int i;
    friend std::ostream& operator<<(std::ostream& o, A const& a) {
        o << a.i;
        return o;
    }
};

Why 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 and right_of keywords to specify:

struct B;

struct A {
     A left_of operator+(B const&) {
         return *this;
     }
};

struct B {
     B right_of operator+(A const&) {
         return *this;
     }
};

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.

谁人与我共长歌 2025-01-14 01:34:50

成员函数:

ostream &operator<<(ostream &os);

确实有效,但不适合您想要的情况。当您执行以下操作时它将被调用:

A a;
a << std::cout;

即对象位于运算符的左侧。

The member function:

ostream &operator<<(ostream &os);

does work, but not for the situation you want. It will be called when you do something like:

A a;
a << std::cout;

i.e. where the object is the left-hand side of the operator.

乱了心跳 2025-01-14 01:34:50

请记住,对于类的非静态成员函数,第一个参数是 this 指针。
所以你的签名是“operator<<”函数,编译后将变成:

ostream &operator<<(A *this, ostream &os);

当您执行以下操作时,这将起作用:

A obj;
obj << std::cout;

将“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:

ostream &operator<<(A *this, ostream &os);

This will work when you do something like:

A obj;
obj << std::cout;

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文