Ссылка, указывающая на нулевой объект - PullRequest
6 голосов
/ 21 июня 2011

Я видел это обсуждение - Проверка на нулевой объект в C ++ , и я был удивлен, что никто не говорил о том, когда ссылка может указывать на нулевой объект.В нашем коде мы обычно используем нулевые объекты.Существуют следующие функции, которые возвращают nullObj.

const Obj&  
nullObj()  
{  
   static obj* nullPtr = NULL;   
   return static_cast<  const Obj&>(*nullPtr);    
}  

На самом деле, когда я снова посмотрел код, чтобы поднять эту тему, у меня возникло несколько вопросов о том, как работает приведенный выше код:

  1. Как этоможно сделать *nullPtr - это потому, что nullPtr является статическим объектом, которому выделена память в куче, и, следовательно, он гарантированно будет иметь некоторое пространство и

  2. , так как мы возвращаемсяконстантная ссылка на obj, создает ли компилятор временный объект (для некоторого вида nullObj ??) или будет ли константная ссылка действовать как псевдоним самого nullPtr?

Ответы [ 3 ]

17 голосов
/ 21 июня 2011

Я был удивлен, что никто не говорил о том, когда ссылка может указывать на нулевой объект

Это потому, что в правильной программе это невозможно.

функция, разыменовывающая нулевой указатель, имеет неопределенное поведение .Компилятору разрешено выдавать код, который, например, вызывает сбой в этой точке.

Тем не менее, одним из возможных эффектов UB является то, что код выполняет то, что, как он думал, будет.Так что нулевые ссылки могут возникнуть.Я никогда не сталкивался с подобным, но если вы это сделаете, то это означает, что в коде есть серьезная логическая ошибка.

Все показанные вами функции ссылки на нуль-объект являются логическими ошибками.

Вам лучше разобраться в этих целях и исправить ситуацию.; -)

Приветствия & hth.,

6 голосов
/ 21 июня 2011

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

Никогда.

(i) Как это можно сделать * nullPtr - это потому, что nullPtr - это статический объект, который выделен памяти в куче и, следовательно, гарантировано, что для разыменования выделено место и адрес?

Это не так. Вы разыменовываете нулевой указатель, который вызывает неопределенное поведение.

(ii) Поскольку мы возвращаем ссылку на const на obj, создает ли компилятор временный объект (для некоторого вида nullObj ??), или ссылка на const будет действовать как псевдоним самого nullPtr?

Нет. На этом этапе компилятору разрешено создавать носовые демоны или черную дыру. Если вам очень повезет, вы получите ошибку сегментации или какой-либо другой вид нарушения доступа.

НЕ ДЕЛАЙТЕ ЭТОГО

1 голос
/ 21 июня 2011

(i) Как это можно сделать * nullPtr - это потому, что nullPtr является статическим объектом, который выделяет память на куча и, следовательно, это гарантировано есть место и адрес для дереф?

Нет, это потому, что nullPtr это указатель, инициализированный NULL, это вовсе не объект.

(ii) Так как мы возвращаем const ссылка на объект, создает ли компилятор временный объект (в какой-то nullObj ??) или будет ли константная ссылка действовать как псевдоним самого nullPtr?

Это будет псевдоним объекта, расположенного по адресу памяти NULL. То есть: когда вы действительно получаете доступ к любому из членов этого ссылочного объекта - вы получите независимо от (обычно нарушение доступа, если система достаточно умна, но на самом деле это может быть что угодно, поведение не определено) .

...