#include <iostream>
int x;
struct A {
A(int a) {
x = a;
}
};
struct B {
B(A a) {
A local_a = a;
}
};
int main() {
x = 0;
std::cout << "Case #0: " << x << std::endl;
B b1(A(1));
std::cout << "Case #1: " << x << std::endl;
int t;
t = 2;
B b2(A(t));
std::cout << "Case #2: " << x << std::endl;
t = 3;
B b3((A(t)));
std::cout << "Case #3: " << x << std::endl;
return 0;
}
Как вы думаете, что должна вывести эта программа? Числа 0, 1, 2 и 3 последовательно для каждого случая?
А она печатает:
Case #0: 0
Case #1: 1
Case #2: 1
Case #3: 3
Почему для случая #2 не произошло присваивание? Куда делась двойка?
Ответ на этот вопрос кроется в наличии рудиментов языка С в грамматике С++.
Вы ведь уже писали про это...
ОтветитьУдалитьhttp://easy-coding.blogspot.com/2009/02/c.html
Писал, точно. Но это было давно, а баг свежий, и тема весьма запутанная. И может кто-то не читал тот пост.
ОтветитьУдалитьХех... Не увидел сцылку...
ОтветитьУдалитьИмхо, объяснение по ссылке очень сложное для такого примера. Здесь получается просто, что выражение
ОтветитьУдалитьB b2(A(t));
интерпретируется как
B b2(A t);
т.е. получается локальная переменная с конструктором без параметров, потому что игнорируются скобочки вокруг (t).
А баг, конечно, бредовый. С++ не устаёт нас "радовать".
выражение
ОтветитьУдалитьB b2(A(t));
интерпретируется как
B b2(A t);
у A нет конструктора по умолчанию
Fanruten, действительно, я и забыл, что явно заданный конструктор убивает неявного...
ОтветитьУдалитьНо я был неправ только частично. Оно действительно интерпретируется как
B b2(A t);
Вот только это не есть создание локальной переменной и вызов конструктора, а означает определение функции b2, с параметром A и возвращающей B. Всё равно проще, чем объяснение по ссылке :)
> Всё равно проще, чем объяснение по ссылке :)
ОтветитьУдалитьНеа :) Объяснение по ссылке просто более полно описывает ситуацию.
Тоже интересно.
ОтветитьУдалитьЧто будет напечатано?
#include
#include
struct Foo
{
const int m_value;
static std::vector ms_vector;
Foo()
:
m_value(ms_vector.size())
{
std::cout << m_value << std::endl;
}
};
Foo f1;
std::vector Foo::ms_vector(5);
Foo f2;
int main()
{
return 0;
}
Что-то подобное спрашивают мега-гуру на собеседованиях )))
ОтветитьУдалить