2016-09-12 5 views
14

Вот минимальный пример:Почему GCC 5.3.0 дает предупреждение при связывании ссылки на «это» указатель

class A 
{ 
    A* const& this_ref; 
public: 
    A() : this_ref(this) {} 
}; 

GCC 5.3.0 дает предупреждение:

предупреждение: временная граница для 'A :: this_ref' только сохраняется до конструктор выходит [-Wextra] A(): this_ref (это) {}

Является this временно? Что ... MSVC 2015 молчит об этом, и ссылаясь на членов класса на this_ref->member вне конструктора в моем случае дает ожидаемое поведение (но может быть просто случай UB, не уверен).


EDIT:

Примечание Этот вопрос проходит один связан как можно дубликата, потому что это не общий вопрос о том, как создать такую ​​ссылку, но о предупреждении GCC (и возможные другие, кроме MSVC компиляторы) производит, когда создавая один.

+2

Возможный дубликат [Возможно ли получить ссылку на «этот» указатель в классе тела без использования имени класса?] (Http://stackoverflow.com/ Вопросы/39258248/is-it-possible-to-get-reference-to-this-pointer-in-class-body-without-using-th) – skypjack

+0

Поскольку 'this' существует только при запуске конструктора и затем перестает есть, временно. (Это именно то, что предупреждает вам предупреждение.) –

+0

Можете ли вы взять адрес 'this'? Не думайте так. Как вы ожидаете, что ссылка будет работать, если у адресата нет адреса? –

ответ

18

Вы создаете болтливую ссылку. Ваш код не отличается от этого кода:

struct X 
{ 
    const int & r; 
    X() : r(5) {} 
};  // ^^^^ dangles 

Там нет «объекта» называется this. this - это ключевое слово , а при использовании в качестве выражения это prvalue (временное), содержащее адрес текущего экземпляра.

Вот еще один пример создания аналогично свисающей ссылки от чего-то, что выглядит как объект, но это не так:

struct Y 
{ 
    int a[10]; 
    int* const & r; 

    Y() : r(a) {} 
}; 

Здесь a именованный объект (именующий), но в инициализаторе r, выражение a - это prvalue (а именно результат распада массива).

Общее сообщение состоит в том, что вы должны быть осторожны с языковой функцией, которая позволяет ссылаться на константные ссылки на значения rvalues. Его основная цель - облегчить вызов функций, но другие его применения намного более увлекательны.

5

Is this Временный?

Чтобы быть точным, this не является временным, но для этого создается временное сообщение.

Во-первых, this является prvalue,

следующие выражения prvalue выражения:

  • this указатель;

Во-вторых, temporary object будет создан при связывании ссылки на prvalue,

Временные объекты создаются when a prvalue is materialized so that it can be used as a glvalue, which occurs (since C++17) в следующих ситуациях:

Именно поэтому GCC дает предупреждение, потому что this_ref привязан к временному созданному. (И затем обмотаться позже, что приводит к UB.)