Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Приведение объекта к ссылке?

Автор вопроса: AfiefhОтветов: 4

В последнее время я читал код OSS и наткнулся на этот своеобразный фрагмент:

class Foo { ..... };
void bar() {
    Foo x;
   Foo *y=new Foo();
   x=(const Foo &) *y;
}

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

  • Я пытаюсь понять фрагмент кода, который я нашел. Afiefh 08.05.2011
  • Вы уверены, что не пропустили (пропустили) разыменование на y? Xeo 08.05.2011
  • О, действительно я. но я до сих пор не знаю, что означает приведение объекта к константной ссылке... Afiefh 08.05.2011
  • Каждый раз, когда вы видите приведение в стиле C в коде C++, это почти наверняка неправильно. 08.05.2011
  • Есть ли у Foo operator= не по умолчанию? n0rd 08.05.2011
  • @Afiefh: Итак, с вашим редактированием вам все еще нужно объяснение кода? В противном случае было бы неплохо полностью удалить вопрос, поскольку он не имеет никакой цели, когда вы спрашиваете о коде, который странен только потому, что вы неправильно его прочитали. jalf 08.05.2011

c++referencecasting

Ответы

Ответ 1 · рейтинг 8 · n0rd

x=(const Foo &) *y; - это назначение. Единственная причина, по которой я вижу явное приведение к константной ссылке, заключается в том, что Foo::operator=(const Foo &) вызывается для присваивания, если Foo::operator=(Foo &) также существует.

Ответ 2 · рейтинг 6 · usta

Строка x=(const Foo &) y; вызывает неопределенное поведение.
Желательно избегать приведения типов в стиле C; их легко ошибиться. Вы заглушаете компилятор, так что они слишком опасны.

Изменить: этот ответ был актуален в то время, когда в вопросе y не было разыменовано до приведения к const Foo &. Ответ на вопрос после редактирования *y см. в ответе, данном n0rd.

Ответ 3 · рейтинг 3 · Xeo

Интересно, что неправильное прочтение кода все еще возможно, если Foo имеет неявный конструктор, который принимает указатель Foo*.

#include <iostream>

class Foo{
public:
  Foo() {}
  Foo(Foo*) { std::cout << "Aha!\n"; }
};

int main(){
  Foo* pf = new Foo;
  Foo f = (const Foo&)pf;

  std::cin.get();
}

См. выходные данные в Ideone.
Интересно, что если вы сделаете конструктор явным, он покажет неопределенное поведение, объясняемое @уста.

Ответ 4 · Seth Carnegie

Вам нужно объявить x после y:

Foo* y = new Foo();
Foo& x = *y;

В качестве альтернативы:

Foo x;
Foo* y = new Foo();
x = (Foo&)*y;

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы