использование ссылки и указателя для перегрузки операторов на больших объектах - PullRequest
2 голосов
/ 06 марта 2011

В книге «Язык программирования C ++» автор приводит следующий пример и несколько утверждений.

class   Matrix {
   double  m[4][4];
   public:
      Matrix( );
      friend Matrix operator+(const  Matrix&, const Matrix&)
};

Matrix  operator+(const  Matrix& arg1, const Matrix& arg2)
{  
  Matrix sum;
  for (int i=0; i<4; i++)
  sum.m[i][j ]=arg1.m[i][j]+arg2.m[i][j];
  return sum;
 }

Книга утверждает, что

ссылки позволяют использовать выражения с обычными арифметическими операторами для больших объектов без чрезмерного копирования. Указатели не могут использоваться, потому что невозможно переопределить значение оператора, примененного к указателю.

Я не понимаю, что означает «чрезмерное копирование» в приведенном выше заявлении. А что касается утверждения «Указатели нельзя использовать, потому что невозможно переопределить значение оператора, примененного к указателю», я просто полностью потерян. Спасибо за объяснение.

Ответы [ 3 ]

7 голосов
/ 06 марта 2011

Если вместо этого operator+ было объявлено как принимающее его операнды по значению, например,

Matrix operator+(Matrix arg1, Matrix arg2)

тогда нужно будет сделать копии arg1 и arg2 для передачи в функцию. Простое добавление матрицы, например,

Matrix x, y;
x + y;

потребует создания копий x и y; фактически вам приходится копировать 32 double с, что, хотя и не очень дорого в этом случае, также не особенно дешево. Когда вы берете аргумент по ссылке, копировать не нужно.

Обратите внимание, что некоторые перегрузки операторов должны принимать свои аргументы по ссылке. В качестве общего примера рассмотрим оператор вставки потока <<: он должен взять операнд std::istream по ссылке, поскольку невозможно скопировать поток.


Указатели нельзя использовать, поскольку операторы не могут быть перегружены для указателей: по крайней мере один операнд каждого оператора перегрузки должен быть классом или типом перечисления. Даже если бы вы могли использовать указатели, синтаксис был бы очень неудобным; вместо использования x + y, как показано выше, вам нужно будет использовать &x + &y.

1 голос
/ 06 марта 2011

Часть "чрезмерного копирования" проста.Если бы в списке параметров не было &, матрицы были бы скопированы при передаче.

Ссылки в некоторой степени похожи на указатели C ++, и они почти всегда реализуются с использованием указателей внутри.Одно из отличий, которое отмечает книга, заключается в том, что вы можете использовать оператор, перегружающий в ссылках на экземпляр класса.

Однако, вы не можете сделать следующее (или любое другое).эквивалентный синтаксис):

Matrix  operator+(const  Matrix *arg1, const Matrix *arg2)

Так что вы не можете написать:

Matrix *a, *b, *c;
c = a + b;
0 голосов
/ 06 марта 2011

Причина, по которой пользователь не может использовать определенные операторы для встроенных типов, таких как указатели или целые, состоит в том, что у них уже есть операторы, определенные для них языком.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...