Вопрос

Уважаемые друзья, я обеспокоен, если я зарабатываю плохое использование ссылок на C ++ в следующем методе GCC жалуется предупреждением «Ссылка на локальную переменную».

MatrizEsparsa& MatrizEsparsa::operator+(MatrizEsparsa& outra){
  MatrizEsparsa me(outra.linhas(),outra.colunas());
  return me;
}

Но со следующими изменениями предупреждение исчезает:

MatrizEsparsa& MatrizEsparsa::operator+(MatrizEsparsa& outra){
  MatrizEsparsa me(outra.linhas(),outra.colunas());
  MatrizEsparsa &ref = me;
  return ref;
}

Правильный ли первый метод (возвращение переменной «ссылки») приемлем?

Это было полезно?

Решение

Нет. ref все еще относится к me который будет уничтожен в конце вызова.

Вы должны вернуть копию вашего результата (не префиксированы &).

MatrizEsparsa MatrizEsparsa::operator+(const MatrizEsparsa& outra) const {
    return MatrizEsparsa(outra.linhas(),outra.colunas());
}

Я также добавил два const Спецификаторы (к параметру и методу), поскольку я сомневаюсь outra Или экземпляр вызывающего вызова должен быть изменен в этом случае. (Я мог быть не прав, но потом твой operator+ будет иметь странный семантический)

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

Обычно, когда вы должны использовать умные трюки, чтобы делать простые вещи, это означает, что что-то не так.

Другие советы

Я думаю, что вы ошиблись своих операторов.

Есть 2:

struct Foo
{
  Foo& operator+=(Foo const&);
  Foo operator+(Foo const&) const;
};

Как вы замечаете, первое возвращает ссылку на себя, вторая нет.

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

Foo operator+(Foo const&, Foo const&);

Это может быть автоматизировано, потому что он громоздкий, используя Boost.Operators:

struct Foo: boost::addable<Foo>
{
  Foo& operator+=(Foo const& rhs)
  {
    // add
    return *this;
  }
};

Немного boost::addable магия автоматически генерирует + Реализация на основе Foo::operator+=.

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

Нет, вы должны вернуть значение здесь, в идеале const ценность. См. Эффективный C ++, пункт 21.

Я предлагаю следующий интерфейс:

const MatrizEsparsa operator+(const MatrizEsparsa& left, const MatrizEsparsa& right);

Обратите внимание, что все равно const ссылка или а const ценность. Возвращая А. const значение не так важно, как возвращение значения или объявление параметров как const Ссылки, но аргументы Скотта Мейерс убедили меня, хотя никто не следует их.

Вы не можете вернуть ссылку, так как объект, на который вы ссылаетесь, будет уничтожен за пределами вашего контроля. Либо поместите «меня» как переменную члена MatrizesParsa, чтобы она сохранилась после выполнения функции, иначе возвращайте указатель, либо Boost Smart_PTR, который указывает на объект.

Видя как это оператор +, хотя, вы, вероятно, хотите вернуть значение, а не ссылку на переменную внутреннюю функцию.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top