当存在要复制的值数组时,在C++中重载=运算符

Raf*_*ini 1 c++ operator-overloading operators

我对C++有些新意,所以我想这是一个非常基本的问题.

假设我有这个课程:

// file Graph.h
class Graph { 
public:
  Graph(int N); // contructor
  ~Graph();     // destructor  
  Graph& operator=(Graph other);
private:
  int * M;
  int N;
};

// file Graph.cpp
Graph :: Graph(int size) {
  M = new int [size];
  N = size;
}

Graph :: ~Graph() {
  delete [] M;
}
Run Code Online (Sandbox Code Playgroud)

我想创建一个赋值运算符,它将复制数组M [] 的内容,但是当我在复制后更改它时不会覆盖它(我认为这是通过不复制实际指针但只复制内容来实现的,不知道如果我是对的).这就是我尝试过的:

Graph& Graph::operator=(Graph other) {
  int i;
  N = other.N;
  M = new int [N];
  for (i = 0; i < N; i++)
    M[i] = other.M[i];
  return *this;
 }
Run Code Online (Sandbox Code Playgroud)

它是否正确?还有其他方法吗?

编辑:我忘了一个重要的问题.为什么我必须声明它Graph& operator=(Graph other);而不仅仅是:Graph operator=(Graph other);我的书中写的是什么(C++:The Complete Reference,2nd ed,Herbert Schildt,355-357页)?

Ale*_* C. 9

规范的方法是使用a std::vector<int>来避免自己管理内存.但是,对于练习来说,正确的做法是:

#include <algorithm>

class Graph
{
public:    
    Graph(size_t n) { data_ = new int[n](); size_ = n; }

    Graph(Graph const& g)
    {
        data_ = new int(g.size_);
        size_ = g.size_;
        std::copy(g.data_, g.data_ + g.size_, data_);
    }

    ~Graph() { delete[] data_; }

    void swap(Graph& g) throw()
    {
        std::swap(data_, g.data_);
        std::swap(size_, g.size_);
    }

    Graph& operator=(Graph g) { g.swap(*this); return *this; }

private:
    int* data_;
    size_t size_;
};
Run Code Online (Sandbox Code Playgroud)

谷歌"复制和交换成语"的代码背后的理由.请注意,您的分配操作符会泄漏内存(原始数组会被覆盖,但永远不会被删除),如果分配失败,最终会导致对象损坏.而且,x = x不会做预期的事情.这三个陷阱很常见,以复制交换方式编写赋值运算符可以避免它们.

编辑:对于您的其他问题,返回引用允许您链接分配,例如a = b = c,对内置类型有效.它可能是也可能不是你想要的(通常是).

  • @davka:是的.赋值运算符"复制并交换*this"其参数.副本在传递值时生成,标准允许编译器在不必要时避免使用此副本. (2认同)