Показать сообщение отдельно
Старый 11.09.2011, 20:20   #12
Knightmare
Дэвелопер
 
Регистрация: 14.02.2007
Сообщений: 1,471
Написано 824 полезных сообщений
(для 2,920 пользователей)
Ответ: Почувствуй себя ламьем

Под спойлером, по просьбам общественности, Кнайтэ дает ответы на все задачи с объяснением почему и как, а так же рассказывает, почему этот тест говно и его составил мудак не разбирающийся в стандарте С++.
Алсо для начала вброс:

Нажмите на изображение для увеличения
Название: 1.png
Просмотров: 819
Размер:	145.4 Кб
ID:	14793

Итак, скандалы, интриги, расследования:

1.
Нажмите на изображение для увеличения
Название: q3_task.PNG
Просмотров: 807
Размер:	6.6 Кб
ID:	14794
Верный ответ: a will have accidental value
Почему: члены объекта будут проинициализированны строго в порядке их объясления (и уничтожены в обратном). Поэтому нет разницы, что с вписке инициализаторов мы написали b перед а, а потом заюзали в инициализации а. Все равно а проинициализируется первым. Т.к. стандарт не говорит нам, чем должны инициализироваться скалярные типы, значение а будет равно какому-то мусору (значение b до инициализации) - 2. Точное значение зависит от платформы. В общем-то, в некоторых условиях можно словить и ошибку компиляции (есть там такой вариант), т.к. компилятор может кинуть ворнинг на неверный порядок инициализаторов, а ворнинги могут считаться и ошибками. Но это очень и очень маловероятно.

2.
Нажмите на изображение для увеличения
Название: q5_task.PNG
Просмотров: 857
Размер:	13.4 Кб
ID:	14795
(вариация где надо вбить ответ)
Верный ответ: 112.
Почему: при new Derived() сперва вызовется конструктор базового класса. В нем дернется виртуальный метод. Но. На этом этапе, объект еще не мутировал в Derived и является типа Base (пункт 10.4.6), поэтому вызовется реализация Base::method() (а если бы это была чисто виртуальная функция мы либо сразу отхватили Segmentation Fault, либо что хуже поломали бы стэк и получили фиерические баги в самых неожиданных местах). В метод будет передано 0, и он вернет 0 + 1 = 1, что и будет выведено. Далее произойдет мутация в Derived и будет выполнен его конструктор. Вызовется Derived::method() с аргументом 2, он вернет 2 - 1 = 1, что и будет выведенно. Далее это все ляжет в автопоинтер, это все херня и ни на что не влияет, исключая то, что как и полагается автопоинтеру, он уничтожит объект которым владеет при выходе из области видимости. Т.е. шаблон автопоинтера инстанциирован с типом Base, произойдет вызов деструктора Base::~Base(). Т.к. деструктор не виртуальный (а он обязан им быть) не произойдет вызова Derived::~Derived(), поэтому в результате будет выведено 2. После чего программа захлопнется. Итог - 112.

3.
Нажмите на изображение для увеличения
Название: q4_task(1).PNG
Просмотров: 851
Размер:	13.4 Кб
ID:	14796
(тут нас спрашивают в чем же проблема этого кода)
Правильный ответ: Base class should declare virtual desctructor
Почему: ну, это было выше, объект типа Derived будет уничтожен как Base, что может привести к утечкам памяти и неверному поведению. Поэтому надо сделать деструктор виртуальным. Вообще, его надо делать виртуальным и у отнаследованного класса, но это не важно. Алсо тут проблема вызова виртуальных методов из конструктора и деструктора., этим можно себе прострелить ногу.

4.
Нажмите на изображение для увеличения
Название: q7_task.PNG
Просмотров: 817
Размер:	2.2 Кб
ID:	14797
ПравильныйТипа правильный ответ: Compilation error because const_cast must be called as const_cast(i)
Почему: вообще этот вопрос придумал идиот. Во-первых, я подозреваю что там должно быть Compilation error because const_cast must be called as const_cast<int>(i). В таком случае у меня для него плохие новости, оно вернет rvalue, и, конечно же, в него невозможно присвоить значение. Еще вариант - Compilation error because const_cast must be called as *const_cast<int*>(&i). О да, мы сможем присвоитьзначение. Но тогда у меня еще более плохая новость для автора вопроса - пункт 7.1.5.1.4 стандарта, который говорит нам, что изменение константы это UB. Все. Никаких других вариантов, мы должны тут ответить вариантом об UB, но он неверный, очень приятно.

5.
Нажмите на изображение для увеличения
Название: q6_task(1).PNG
Просмотров: 847
Размер:	6.3 Кб
ID:	14798
ПравильныйТипа правильный ответ: 132242
Почему: сразу - автор неимевший дела с кросс-платформенным программирвоанием мудак и ответ действителен только для MSVC, другой компилятор скорее всего выдаст 13242. Теперь растолковывавние: При конструировании объекта типа B сперва вызовется конструктор А (выход 1), потом уже конструктор В (выхлоп 3). После этого что поизодйет в студии - она создаст проксирующий объект типа А из В (используя конструктор копирования A(const A & other), который не определен и, следовательно, ничего не выведет, т.к. будет использован сгенерированный компилятором, тупо копирующий все поля класса), а потом из него скопирует этим же конструктором копирования аргумент для func (и опять конструктор ничего не выведет). После этого функция отработает свое (тупо ничего не сделает) и аргумент будет убит. Вызоается деструктор А (выхлоп 2). После этого убъется проксирующий объект (опять 2). Вот это место никак не оговоренно стандартом и проксирующий объект инициатива студии (понятия не имею зачем, может есть какие-то реальные причины). Тот же GCC не будет создавать ничего лишнего и напрямую скопирует аргумент из b, поэтому и выведет только одну двойку. Далее все просто и по стандарту - вызовется деструктор B (выхлоп 4) и за них деструктор базового класса А (выхлоп 2). Поэтому и получает 132(2)42.

6.
Нажмите на изображение для увеличения
Название: q8_task.PNG
Просмотров: 791
Размер:	12.5 Кб
ID:	14799
Правильный ответ: Provide implementation of copy constructor and assignment operator
Почему: тут думаю все ответили правильно, ибо тривиальный вопрос. Хотя на самом деле хватит конструктора копирования, т.к. String b = a; это вызов конструктора копирования, а не вызов дефолтного конструктора и следом оператора присваивания. А нужно это все для того, чтобы у каждой строки был свой буфер символов (который уничтожится в деструкторе).

Собственно и все, ничего сложного и сверхъестественного в этих вопросах нет, даже нигде не присутствует черная шаблонная магия (а я могу на эту тему дать задачу, вот там действительно глубокое понимание стандарта С++).


Таким образом, человеки посчитавшие этот тест неибацо сложным могут облить себя бензином и поджечьидут курить стандарт С++
(Offline)
 
Ответить с цитированием
Эти 16 пользователя(ей) сказали Спасибо Knightmare за это полезное сообщение:
ANIK123 (10.10.2011), baton4ik (11.09.2011), den (11.09.2011), Dream (11.09.2011), falcon (11.09.2011), ffinder (11.09.2011), Harter (15.09.2011), HolyDel (11.09.2011), LLI.T.A.L.K.E.R. (11.09.2011), moka (11.09.2011), Mr_F_ (11.09.2011), NitE (11.09.2011), pepel (11.09.2011), Reks888 (11.09.2011), SBJoker (11.09.2011), St_AnGer (11.09.2011)