Рассмотрим следующий код C ++:
#include<iostream>
using namespace std;
class Test {
int &t;
public:
Test (int &x) { t = x; }
int getT() { return t; }
};
int main()
{
int x = 20;
Test t1(x);
cout << t1.getT() << " ";
x = 30;
cout << t1.getT() << endl;
return 0;
}
Это показывает следующую ошибку при использовании компилятора gcc
est.cpp: In constructor ‘Test::Test(int&)’:
est.cpp:8:5: error: uninitialized reference member ‘Test::t’ [-fpermissive]
Почему компилятор не вызывает конструктор напрямую?
Это связано с тем, что ссылки могут быть инициализированы только в списке инициализаторов. использование
Test (int &x) : t(x) {}
Пояснение: ссылка может быть установлена только один раз, место, где это происходит, это список инициализатора. После того, как это сделано, вы не можете установить ссылку, а только присвоить значения ссылочному экземпляру. Ваш код означает, что вы пытались присвоить что-то экземпляру, на который ссылаются, но ссылка никогда не инициализировалась, следовательно, он не ссылается ни на один экземпляр int
и вы получите ошибку.
Мой компилятор выдает эту ошибку:
ошибка C2758: ‘Test :: t’: должен быть инициализирован в базе конструктора / инициализаторе члена
И это именно то, что вы должны сделать. Рекомендации должен инициализироваться в списке инициализаторов:
#include<iostream>
using namespace std;
class Test {
int &t;
public:
Test (int &x) : t(x) { } // <-- initializer list used, empty body now
int getT() { return t; }
};
int main()
{
int x = 20;
Test t1(x);
cout << t1.getT() << " ";
x = 30;
cout << t1.getT() << endl;
return 0;
}
Объяснение:
Если ссылка отсутствует в списке initiliazer, компилятору почти невозможно определить, инициализирована ли ссылка. Рекомендации должен быть инициализирован. Представьте себе этот сценарий:
Test (int &x, bool b)
{
if( b ) t = x;
}
Теперь вызывающему конструктору решать, был ли создан правильный код. Этого не может быть. Компилятор должен убедиться, что ссылка инициализирована во время компиляции.