C ++运算符重载返回指针

时间:2015-05-29 19:00:30

标签: c++ operator-overloading dynamic-memory-allocation

我是用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”,并返回一个副本。处理大型物体时,这对性能不利?

如下例所示,使用动态内存不是更好:

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

或者我看到了这个错误?

提前致谢

2 个答案:

答案 0 :(得分:2)

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

有很多方法可以完全不复制;命名的返回值优化(NRVO)和移动分配是相关的想法。

即使你决定要做一些像你的建议一样的事情,你也不应该像你一样实现它,因为它有错误的语义:你已经operator+返回指针到事物而不是一件事。此外,使用指针(特别是裸指针)是有风险的,因为它为您提供了更多犯错的机会。

如果你想在这些行上实现某些东西,你需要将指针语义包装在一个提供值语义的类中。

答案 1 :(得分:0)

根据现行标准,这有点不同:

#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.