Возвращаемый адрес или локальная переменная или временное предупреждение С++
Возможный дубликат:
предупреждение С++: адрес локальной переменной
Привет,
Когда я пишу этот код:
//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) не расширен; временное разрушен в конце полное выражение в обратном утверждение".
Поэтому ваша функция пытается вернуть ссылку на ячейку памяти, срок хранения которой уже завершен, и объект был уничтожен.
Поэтому предупреждение. Обратите внимание, что эта ситуация не требуется для явного определения Стандартом и, следовательно, предупреждения.