【问题标题】:C++: Operator Overloading Problems?C++:运算符重载问题?
【发布时间】:2015-10-06 15:39:19
【问题描述】:

我的朋友有一些关于运算符重载的代码。代码如下:

class Bar
{
public:
    int num;
    Bar(int n){
        num = n;
    }
};
class FooPa
{
// Consider it empty
};
class Foo : public FooPa
{
    Bar *b1, *b2;
    Bar operator + ( )// **I don't understand this function, how can I use it?**
    {
        int value=  b1->num +b2->num;
        Bar * b = new Bar(value);
        return (*b);
    }
};

我不明白函数“Bar operator +()”。他想将“b1.num”和“b2.num”数学相加,然后返回一个新对象。是否有意义?这个新的运算符“+”怎么用,谁能举个例子?

【问题讨论】:

  • operator+ 的原型错误。你不能使用它。这不是提到内存泄漏和一切。
  • 来自没有经验的程序员的否决投票问题是 SO 的新时尚。 :P
  • @SergeyA 它是一个一元 + 运算符重载,除了内存泄漏之外很好。
  • @a4anurag:“很好”?从未初始化的指针中读取呢?即使实现是正确的,您认为一元加号会使自定义类型更易于使用吗?
  • @ChristianHackl 这些指针初始化是 Foo 的构造函数未重载的 + 运算符的工作。此外,似乎 OP 需要澄清函数签名和较少的实现。

标签: c++ operator-overloading


【解决方案1】:

原型Bar Foo ::operator +() 表示一元加号运算符。可以这样使用:

Foo f;
Bar b = +f; // "+f" is the unary plus operator

【讨论】:

    【解决方案2】:

    通常,运算符重载意味着您​​正在为现有运算符提供新定义。有一些例外和规则需要遵守(google it)。

    基本语法是

     <return type> operator "symbol" (parameters)
    

    例如:假设你有一个这样的类复合体

    class complex{
    int real,img;
    }
    

    您需要重载运算符 +,使其可以像这样执行两个复数的加法

    public:
    void operator+(complex ob)
    {cout<<real+ob.real<<" + i "<<img+ob.img; }
    

    规则: 运算符必须与这样的类对象一起使用

    complex a,b;
    a+b;
    

    注意: 这里 a 是调用对象(((a.)+b)),这是由编译器处理的)。 b 与 a 没有任何联系,除了它们具有相同的数据类型。所以 b 作为参数传递(所有二元运算符都必须有参数)。

    在您的示例中,您已经重载了一元 + 运算符。它基本上与二进制重载相同,但您不能传递参数。 希望你理解运算符重载的概念

    【讨论】:

      【解决方案3】:

      看不懂函数Bar operator +()"

      确实如此。它没有多大意义(当然,对于像“Foo”和“Bar”这样的示例名称,很少有事情做)。它声明了一个一元加号运算符

      这已经是该语言的一个非常奇特的特性。这是一个例子:

      #include <iostream>
      
      int main()
      {
          int i = 5;
          std::cout << +i << "\n";
      }
      

      不出所料,该程序将打印5。不过,它有 一些 用例。请参阅What is the purpose of unary plus operator on char array?What does the unary plus operator do?

      在您的代码中,您可以这样调用运算符:

      Foo f;
      +f;
      

      您显示的代码的另一个奇怪之处是,运算符返回 Bar 而不是 Foo,正如人们所期望的那样(尽管同样,对于“Foo”和“Bar”这样的名称,人们无法确定关于代码的假定意图)。

      操作符也是private,也就是说只能在Foo自己的函数或者朋友里面使用。这很难说是对的。

      int value=  b1->num +b2->num;
      

      这是未定义的行为,因为您尝试通过未初始化的指针访问成员[*]。或者您没有向我们展示 b1b2 被初始化和/或分配的代码。

      Bar * b = new Bar(value);
      return (*b);
      

      这会造成内存泄漏,因为位于由new 动态分配的内存中的Bar 对象被复制并且永远不会被销毁,因为指向它的唯一指针(b)丢失了。


      也许您的朋友想创造将BarFoo 加在一起的可能性。如果是这样的话,那么很多事情都出了问题。该函数有错误的接口错误的实现。

      请转至http://en.cppreference.com/w/cpp/language/operators 并阅读有关二元算术运算符的部分以了解如何正确完成。

      或者暂时忘记运算符重载。似乎缺少一些有关该语言的基本知识(例如nullptr/指针初始化/一般指针)。


      [*]不是nullptrs 作为这个答案的先前版本所说的

      【讨论】:

        猜你喜欢
        • 2014-04-14
        • 1970-01-01
        • 1970-01-01
        • 2011-03-22
        • 2018-05-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多