#c #class #reference #constants
#c #класс #ссылка #константы
Вопрос:
У меня всегда складывается впечатление, что я не должен использовать ссылку для инициализации члена класса, потому что
- Я не знаю время жизни ссылки и
- Если ссылочное значение изменяется за пределами класса, соответствующий член класса также изменится на новое значение.
Но после тестирования следующего кода я в замешательстве…
class Test
{
public:
Test(intamp; i) :m_i(i) {}
int m_i;
};
class Test3
{
public:
Test3(intamp; i) :m_i(i) {}
const intamp; m_i;
};
int main()
{
{
std::cout << "n// Test 1" << std::endl;
int i = 10;
Test oTest(i);
printf("oTest.i = %dn", oTest.m_i);
i = 20;
printf("oTest.i = %dn", oTest.m_i);
}
{
std::cout << "n// Test 1.1" << std::endl;
int* i = new int;
*i = 10;
Test oTest(*i);
printf("oTest.i = %dn", oTest.m_i);
*i = 20;
printf("oTest.i = %dn", oTest.m_i);
delete i;
printf("oTest.i = %dn", oTest.m_i);
}
{
std::cout << "n// Test 3" << std::endl;
int i = 10;
Test3 oTest(i);
printf("oTest.i = %dn", oTest.m_i);
i = 20;
printf("oTest.i = %dn", oTest.m_i);
}
{
std::cout << "n// Test 3.1" << std::endl;
int* i = new int;
*i = 10;
Test3 oTest(*i);
printf("oTest.i = %dn", oTest.m_i);
*i = 20;
printf("oTest.i = %dn", oTest.m_i);
delete i;
printf("oTest.i = %dn", oTest.m_i);
}
return 0;
}
Вывод выглядит следующим образом:
// Test 1
oTest.i = 10
oTest.i = 10 <---- Why not 20?
// Test 1.1
oTest.i = 10
oTest.i = 10 <---- Why not 20?
oTest.i = 10 <---- Why not some garbage number?
// Test 3
oTest.i = 10
oTest.i = 20
// Test 3.1
oTest.i = 10
oTest.i = 20
oTest.i = 20 <---- Why not some garbage number?
Большое спасибо за ваш комментарий.
Ответ №1:
Ваш Test(intamp; i) :m_i(i)
вызывает конструктор копирования, и поскольку ваше поле является int, а не int amp; , тесты 1 и 1.1 всегда выводят исходные 10.
В тесте 3.1 нет требования, чтобы доступ к памяти, которая была освобождена / удалена с помощью, приводил к мусору. (Существуют отладочные компиляторы, которые намеренно помещают отдельный шаблон в освобожденную память, но это часть их природы отладки.) Ничто в вашей игрушечной программе не изменяет значение, на которое указал i
, так что вам это «сойдет с рук». В корпоративной программе вы получите труднодоступный «Heisenbug«.