2014-12-10 2 views
0

Мне нужно вызвать функцию, которая возвращает мне объект. Проблема в том, что объект имеет деструктор, который может испортить данные до того, как выход функции будет назначен другому объекту. В моей программе, у меня есть оператор +, который добавляет две матрицы и возвращает сумму обоих матриц:Должен ли я полагаться на компилятор NRVO?

C=A+B 

По Имя Возвращаемое значение оптимизации (NRVO), следующий код не должен вызывать право деструктора От кого:

Matrix operator+(const Matrix &m1, const Matrix &m2) 
{ 
    Matrix sum; 
    m1.clone(sum); 
    for... 
     for... 
      sum.members[i][j]+=m2.members[i][j]; 
    return sum; 
} 

Моя проблема в том, что я не уверен в доверии к NRVO, поскольку это зависит от компилятора. Если я передам код кому-то другому, он может скомпилировать код, и его компилятор даст другой результат.

Итак, есть ли способ заставить компилятор дать мне то, что мне нужно, или я должен изменить свой код на нежелательную форму следующим образом?

Matrix sum(Matrix &result, const Matrix &m1, const Matrix &m2) 

редактировать:

Просто объяснить более, я полагаю, рассматривая NRVO, то probram работает следующим образом:

compiler reaches to C=A+B 
operator + is called 
object sum is created 
object sum is calculated as sum of m1 and m2 
sum is returned but its destructor is not called 
the value of sum is directed to variable C 
after function containing variable C reaches end, the destructor of C is called. 

Хотя когда NRVO не применяется, я ожидаю:

compiler reaches to C=A+B 
operator + is called 
object sum is created 
object sum is calculated as sum of m1 and m2 
sum is returned and its destructor is called which releases all data allocations 
the return value of the operator+ is already destroyed so an invalid data is associated to variable C 
... 
+1

Если ваш класс делает то, что вы говорите это вам нужно исправить. – juanchopanza

+0

Код, который вы пишете, не должен зависеть от конкретной оптимизации компилятора для правильной работы. –

+2

Похоже, вам нужно прочитать о жизни объектов. Пожалуйста, укажите места в коде, где вы ожидаете вызовы деструктора, и мы должны уметь это прояснить. – Pradhan

ответ

3

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

Это не проблема. Объект будет скопирован правильно или ненужная копия будет устранена путем оптимизации. Если ваша копия ctor реализована правильно, конечный результат будет таким же (за исключением менее оптимального кода). Если копия объекта является чрезмерно дорогой, вам, вероятно, следует использовать копию для семантики записи, и фактический объект Matrix будет тонкой оболочкой для реального объекта, созданного в куче.

Что на самом деле произойдет, когда NRVO не применяется:

compiler reaches to C=A+B 
operator + is called 
object sum is created 
object sum is calculated as sum of m1 and m2 
temporary object of type Matrix created as a copy of object sum 
object sum destroyed 
temporary assigned to C 

как вы можете видеть конечный результат один и тот же, только менее эффективным (временный объект, созданный)

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