Контрольная переменная в определении класса

Я изучаю С++, и я читал, что все ссылки должны быть инициализированы после объявления, и не может быть "неинициализированных ссылок". Но что, если ссылочная переменная является членом класса?

class test
{
    int &k;
};

int main()
{
    test *abc = new test;
}

Эта программа компилируется и работает нормально (в g++, никаких предупреждений). Однако abc->k является ссылкой, но для чего он инициализирован? Или это "неинициализированная ссылка" какого-то рода или что-то еще?

Ответ 1

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

Я считаю, что gcc не должен компилировать это, но я получил предупреждение "нестатическая ссылка" int & test:: k в классе без конструктора ".

test является не-POD-структурой, так как он содержит ссылочный элемент. (9 [класс]/4)

new test default - инициализирует динамически распределенный класс. (5.3.4 [expr.new]/15)

По умолчанию инициализировать объект типа test означает вызов неявно объявленного и неявно определенного конструктора по умолчанию. (8.5 [dcl.init]/5)

Неявно определенный конструктор по умолчанию эквивалентен конструктору по умолчанию с пустым mem-initialized-list и пустым телом функции. (12.1 [class.ctor]/7)

Далее:

Неявно определенный конструктор по умолчанию выполняет набор инициализаций класс, который будет выполняться написанным пользователем конструктором по умолчанию для этого класса с пустым списком mem-initializer (12.6.2) и пустым телом функции. Если этот пользовательский конструктор по умолчанию будет плохо сформирован, программа будет плохо сформирована.

Если объект не является именем в списке mem-initializer и член не относится к типу класса [с дополнительными ограничениями], то объект не инициализируется.

В противном случае объект не инициализируется. Если объект имеет тип const-type или ссылочный тип, [или...] программа плохо сформирована. "(12.6.2 [class.base.init]/4)

Ответ 2

Ваш код на самом деле вообще не будет компилироваться на Visual С++. В общем, лучше оставить как можно меньше шансов. Вам нужно инициализировать элементы refence, используя список инициализаторов в конструкторе:

class test
{
public:
 test(int& x) : k(x)
 {
 }
 int& k;
};

Ответ 3

class test
{
    public:
        test(int x) : k(x)
        {
        }
    int& k;
};

У меня есть сомнения в том, как инициализируется ссылка. Когда стек стека для ctr снят со стека, ссылка больше не будет действительной.