Для инициализации ссылочного члена требуется временная переменная C ++ - PullRequest
13 голосов
/ 09 ноября 2009
struct Div
{
   int i;
   int j;
};   

class A
{
    public:
             A();
             Div& divs;
};

В моем определении конструктора у меня есть следующее

A::A() : divs(NULL)
{}

Я получаю следующую ошибку:

  Error72 error C2354: 
  'A::divs' : initialization of reference member requires a temporary variable 

Ответы [ 12 ]

33 голосов
/ 09 ноября 2009

Ссылка должна быть инициализирована для ссылки на что-либо; он не может ссылаться ни на что, поэтому вы не можете создать класс по умолчанию, содержащий его (если, как другие не предлагают, вы определяете глобальное «нулевое» значение). Вам понадобится конструктор, которому дано Div для ссылки на:

explicit A(Div &d) : divs(d) {}

Если вы хотите, чтобы он был "нулевым", вам нужен указатель, а не ссылка.

12 голосов
/ 09 ноября 2009

divs - это ссылка, а не указатель. Вы не можете установить его в NULL, он должен указывать на какой-то реальный объект. Лучшее, что можно сделать здесь, это, вероятно, определить статический / глобальный экземпляр Div, который вы произвольно определяете как «Null Div» (установите его значение на то, что вы вряд ли когда-либо будете использовать) и инициализируйте div для этого. Примерно так:

struct Div
{
   int i;
   int j;
};   

Div NULL_DIV = { INT_MAX, INT_MAX };

class A
{
    public:
             A();
             Div& divs;
};


A::A() : divs(NULL_DIVS)
{
}

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

* Обратите внимание, что вы не можете использовать ссылку на константу, если вы не отбрасываете константу, потому что по умолчанию компилятор не разрешает вам присваивать ссылочную ссылку неконстантной ссылке.

8 голосов
/ 09 ноября 2009

Во-первых, вы не можете иметь нулевую ссылку. Во-вторых, все ссылки на переменные в классе должны быть инициализированы во время создания.

6 голосов
/ 09 ноября 2009

На «английском»: ссылка относится к что-то . Он не может ссылаться на ничто (ноль). Вот почему ссылки безопаснее использовать, чем указатели.

3 голосов
/ 09 ноября 2009

Сообщение компилятора является одним из тех сообщений, которые не имеют смысла с языковой точки зрения, но раскрывают внутреннюю работу компилятора, последовательность, в которой работает его внутренняя логика.

В вашем случае вы используете rvalue (NULL) для инициализации ссылки. Когда такая инициализация разрешена, значение преобразовывается во временный объект, к которому будет привязана ссылка. Итак, компилятор сразу понял это и сообщил вам об этом с диагностическим сообщением.

В действительности, подобный трюк допустим только для const ссылок, поэтому ваш код не работает, поскольку в нашем случае ссылка не const. Кроме того, ссылка struct, как и ссылка в вашем коде, не может быть инициализирована с NULL rvalue (который имеет целочисленный тип), поэтому она также прерывается по этой причине.

Хотя сообщение компилятора вводит в заблуждение. Текст сообщения, по-видимому, подразумевает, что инициализировать ссылки на элементы временными объектами незаконно. На самом деле, это допустимо в C ++ (как только вышеуказанные проблемы будут исправлены), хотя это не имеет смысла. Но, как мне кажется, когда плохо сформированный код сопровождается хотя бы каким-то сообщением об ошибке, все должно быть в порядке ...

3 голосов
/ 09 ноября 2009

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

3 голосов
/ 09 ноября 2009

Ссылки должны ссылаться на что-то. В языке C ++ не существует нулевой ссылки. Если член может не иметь значения, то это должен быть указатель, или boost::optional, или какой-то подобный тип.

Ссылка должна быть инициализирована для ссылки на действительный объект.

2 голосов
/ 09 ноября 2009

Простые и простые:

Ссылка никогда не может быть NULL.

1 голос
/ 30 июня 2010
class A
{
    Div & ref(Div div) { return div; }
    public:
       A() : divs(ref(Div())) {};
       Div& divs;
};
1 голос
/ 09 ноября 2009

Как отмечено в других сообщениях, ссылки (Div &) не могут быть нулевыми. Поэтому самое простое изменение, которое вы можете сделать, - предоставить ссылку в конструкторе и инициализировать ваш ссылочный элемент. Вот так

class A
{
    public:
             A(Div& inDivs);
             Div& divs;

};

public A::A( Div& inDivs )
: divs( inDivs )
{}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...