Возвращаемый адрес или локальная переменная или временное предупреждение С++

Возможный дубликат:
предупреждение С++: адрес локальной переменной

Привет, Когда я пишу этот код:

//Returns the transpose matrix of this one
SparseMatrix& SparseMatrix::transpose()const{
    vector<Element> result;
    size_t i;
    for(i=0;i<_matrix.size();++i){
        result.push_back(Element(_matrix.at(i)._col, _matrix.at(i)._row, _matrix.at(i)._val));
    }

    return SparseMatrix(numCol,numRow,result);
}

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

Ответ 1

Вы возвращаете ссылку, а не фактический объект. Обратите внимание на & здесь:

SparseMatrix& SparseMatrix::transpose()const{

Если вы хотите вернуть фактический объект, удалите его &.

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

Ответ 2

В С++ локальные переменные "автоматически" разрушаются при выходе из области видимости. Ваш оператор return создаст безымянную временную переменную типа SparseMatrix, которая немедленно выйдет из области видимости. Следовательно, возврат ссылки на него не имеет смысла.

Может быть проще вернуть по значению: тогда будет возвращена копия временного. Компилятор может оптимизировать это (копировать elision).

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

SparseMatrix* SparseMartix::transopse()const{


     //...
     return new SparseMatrix(...);

}

Но тогда вам нужно самому позаботиться о жизни возвращаемого объекта.

Ответ 3

Конструкция "T()" создает временный тип "T", который в основном не является Lvalue (но Rvalue).

$12.1/11 - "Функциональный тип обозначения преобразование (5.2.3) можно использовать для создавать новые объекты своего типа. [ Примечание. Синтаксис выглядит как явный вызов конструктора.

12 Объект, созданный таким образом, не имеет названия. [Примечание: 12.2 описывает время жизни > временных объектов. -конец note] [Примечание: явные вызовы конструктора не дают lvalues, см. 3.10. -end note] Время жизни этого временного является окончанием полного выражения, то есть конечной точки с запятой после выражения.

$12.2/3 -" Временные объекты разрушен как последний шаг в оценивая полное выражение (1.9) что (лексически) содержит точку где они были созданы. Это правда даже если эта оценка заканчивается бросая исключение. Значение вычисления и побочные эффекты уничтожение временного объекта связанных только с полное выражение, а не с какой-либо конкретной Подвыражение ".

$12.2/5- 'Время жизни временного связанный с возвращаемым значением в функция return return (6.6.3) не расширен; временное разрушен в конце полное выражение в обратном утверждение".

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

Поэтому предупреждение. Обратите внимание, что эта ситуация не требуется для явного определения Стандартом и, следовательно, предупреждения.