C++ 运算符重载 return 指针

C++ operator overloading return pointer

我对 C++ 编程还很陌生,我想知道一些事情:

每当我在 C++ 中看到运算符重载时,它都是这样完成的:

#ifndef STONE_H
#define STONE_H

class Stone {
    private:
    int weight;

    public:
    .......

    Stone operator+(const Stone& s) {
        Stone stone;
        stone.weight = this->weight + s.weight;
        return stone;
    }

    .......
}


#endif

但是当调用“+”运算符时,它会创建一个对象 "stone",并且 returns 是它的一个副本。这在处理大对象时对性能不利吗?

像下面的例子那样使用动态内存不是更好吗:

Stone * operator+(const Stone& s) {
    Stone * stone = new Stone;
    stone->weight = this->weight + s.weight;
    return stone;
}

还是我看错了?

提前致谢

尝试推理并不是评估性能的特别准确的方法:您需要实际编写一个程序来衡量一种实现是否优于另一种实现。

有多种方法可以完全避免复制;命名的 return 值优化 (NRVO) 和移动分配是这里的相关想法。

即使您决定要按照您的建议做某事,您也不应按原样实施,因为它的语义错误:您已经 operator+ return指向事物而不是事物的指针。此外,使用指针(尤其是裸指针)是有风险的,因为它给了你更多犯错的机会。

如果你想按照这些思路实现某些东西,你需要将指针语义包装在提供值语义的 class 中。

原来在现在的标准上,这个有点不一样:

#include <iostream>

class big {
  int* v; // Demonstration purposes. A smart pointer or a standard container would be better.
  public:
  big& operator+=(big& o) {
    for (int i=0;i<1000;++i) {
      v[i] += o.v[i];
    }
    return *this;
  }

  big(int val = 0)
      :    v{new int[1000]} // We're using RAII to prevent resource leaking.
  {
    std::cout << "a construction.\n";
    for (int i=0;i<1000;++i) {
      v[i] = val;
    }
  }

  // Copy constructor
  big(big& o) 
      :    v{new int[1000]}
  {
    std::cout << "a copy construction.\n";
    for (int i=0;i<1000;++i) {
      v[i] = o.v[i];
    }
  }

  // Move assignment
  big& operator=(big&& o) {
    std::cout << "a move assignment.\n";
    if (v) delete[] v;
    v = o.v;
    o.v = nullptr;
  }

  // Move constructor
  big (big&& o) {
    std::cout << "a move construction.\n";
    v = o.v;
    o.v = nullptr;
  }

  ~big() {
    if (v) delete[] v;
  }
};

// a will be move-constructed if using a temporary, or copy-contructed if not.
// The result will always be passed by a cheap move
big operator+(big a, big& b) {
  return std::move(a += b);
}

int main() {
  big a{1};
  big b{2};
  big c{3};

  big d = a+b+c;
}

输出:(添加了注释)

a construction. // Constructed a
a construction. // Constructed b
a construction. // Constructed c
a copy construction. // a+b <- a copied into parameter "a" of operator+. b is passed by reference.
a move construction. // The temporary from the operation above, moved into parameter "a" of operator+. c is passed by reference.
a move construction. // d is move constructed from the temporary generated by a+b+c.