2014-01-10 2 views
1

Я запутался в семантике перемещения C++ при использовании с перегрузкой оператора.Смутно о семантике перемещения с перегрузкой оператора

Например: (заголовок)

#pragma once 
#include <vector> 
namespace Mat { 
    using namespace std; 
    template <class T = double> 
    class Matrix { 
     public: 
     vector<vector<T>> &data; 
     size_t Rows; 
     size_t Cols; 
     // ctor 
     Matrix(size_t rows = 1, size_t cols = 1) : 
      data(*(new vector<vector<T>>(rows, vector<T>(cols)))) { 
      Rows = rows; 
      Cols = cols; 
      } 
     // copy assignment 
     Matrix &operator=(const Matrix &m) { 
      cout << "Copy =" << endl; 
      delete &data; 
      Rows = m.Rows; 
      Cols = m.Cols; 
      data = *(new vector<vector<T>>(m.data)); 
      return *this; 
      } 
     // move assignment 
     Matrix &operator=(Matrix &&m) { 
      cout << "Move =" << endl; 
      Rows = m.Rows; 
      Cols = m.Cols; 
      data = m.data; 
      return *this; 
      } 
     // destructor 
     ~Matrix() { 
      delete &data; 
      } 
     // addition 
     Matrix &operator+(const Matrix &right) { 
      const auto &left = *this; 
      auto &result = *(new Matrix<T>(left.Rows, left.Cols)); 
      for (size_t r = 0; r < Rows; r++) { 
       for (size_t c = 0; c < Cols; c++) { 
        result.data[r][c] = left.data[r][c] + right.data[r][c]; 
        } 
       } 
      return result; 
      } 
     }; 
    } 

(основная/водитель)

int _tmain(int argc, _TCHAR* argv []) { 
    Mat::Matrix<double> mat1(3,3); 
    Mat::Matrix<double> mat2(3, 3); 
    std::default_random_engine generator; 
    std::uniform_int_distribution<int> distribution(1, 6); 
    for (int r = 0; r < 3; r++) { 
     for (int c = 0; c < 3; c++) { 
      mat1.data[r][c] = distribution(generator); 
      mat2.data[r][c] = distribution(generator); 
      } 
     } 
    Mat::Matrix<double> mat3; 
    mat3 = mat1 + mat2; 
    } 

Когда я выполнить этот код. Он указывает, что «mat3 = mat1 + mat2» использует оператор присваивания копии. Я ожидал (и хотел) использовать оператор присваивания перемещения. Я использую VS2013.

Может кто-нибудь объяснить, почему это происходит и как я могу получить желаемую семантику перемещения? Благодаря

+0

О, мое ... Что происходит с этим «новым» и ссылкой? Почему вы не можете просто построить «вектор» внутри класса? – Shoe

+0

Кто учит вас C++? Это абсолютно ужасно. Просто сохраните 'vector >', а не ссылку на него. Затем удалите код для операторов присваивания и деструктора, поскольку значения по умолчанию будут правильно реализованы. И не используйте 'new'. –

ответ

1

Ваш operator+ не только пропускает память, но также возвращает Mat::Matrixпо ссылке. Поэтому выражение mat1 + mat2 может связывать только с:

Matrix &operator=(const Matrix&); 

То, что вы хотите сделать, это вернуть Matrix по значению, вместо этого. Наконец, я вижу, что вы используете new повсюду. Вам не требуется динамическое размещение, особенно с std::vector.

0

Среди кучи других проблем, ваш operator+() является возвращающей не- ссылки const л-значения, а не временный г-значение ... Таким образом, это будет связываться со ссылкой на const л-значения в копии оператор присваивания.

Смежные вопросы