LINUX.ORG.RU

Ты хоть сам то понял, что тут написано?

UnDeFiNeD
()

На уровне сферических классов A B C D - нормально. На более конкретном уровне может быть плохо.

Ну на public C.b некоторые могут наехать.

Legioner ★★★★★
()
Ответ на: комментарий от Legioner

Кстати на паттерн "стратегия" немного похоже.

Legioner ★★★★★
()

> A a; D() : C(a) {}

формально это undefined behaviour

The lifetime of an object is a runtime property of the object. The lifetime of an object of type T begins when: storage with the proper alignment and size for type T is obtained, and if T is a class type with a non-trivial constructor (class.ctor), the constructor call has completed.

ты пытаешься использовать a (пусть даже и в виде ссылки) до того как начнется его жизнь.

dilmah ★★★★★
()
Ответ на: комментарий от dilmah

in particular, before the lifetime of an object starts and after its lifetime ends there are significant restrictions on the use of the object, as described below, in class.base.init and in class.cdtor.

dilmah ★★★★★
()
Ответ на: комментарий от dilmah

А может 3.8 пункт 6 как раз работает, и в данном случае всё нормально? Типа мы ссылку только сохраняем и никак не используем.

yz
() автор топика
Ответ на: комментарий от yz

> А может 3.8 пункт 6 как раз работает, и в данном случае всё нормально? Типа мы ссылку только сохраняем и никак не используем.

Только с точки зрения дизайна - получается говнясто. В базовом классе прийдется помнить, что ссылку нельзя использовать, из-за особенностей реализации класса-предка.

fmj
()
Ответ на: комментарий от fmj

Ну, да, в конструкторе нельзя...

yz
() автор топика

Плохо, плохо. Конструктор C::C для того экземпляра C, который внутри D, будет вызван раньше конструктора переменной D::a, поскольку при создании экземпляров классов сперва вызываются конструкторы родительских классов, а уж потом - конструкторы членов. Таким образом, C::C отработает на еще неинициализированном объекте D::a.

gzh
()
Ответ на: комментарий от gzh

А нам по идее и не надо, чтобы D::a был инициализирован, достаточно, чтобы аллоцирован, судя по 3.8 пункт 6 стандарта.

yz
() автор топика
Ответ на: комментарий от yz

Не уверен что понимаю, что Вы имеете в виду.

Конструктор C::C, вызываемый в D::D, использует неинициализованный объект. Пока все объекты пустые и не имеют смысла - скорее всего, ничего плохого не случится. Если представить себе что у D::a есть, к примеру, таблица виртуальных функций - все, с высокой вероятностью обращение к методам своего аргумента в C::C вызовет крах процесса.

gzh
()
Ответ на: комментарий от gzh

ну ты ж видел, что у него только сохраняется ссылка -- в конструкторе базового класса эта ссылка нигде не подвергается преобразованию lvalue->rvalue -- так что с точки зрения стандарта, как уже писали выше, очень вероятно, что все верно.

dilmah ★★★★★
()
Ответ на: комментарий от dilmah

Если рассматривать весь код в совокупности - то да, он, возможно, будет работать.

Но если рассматривать определение только класса D - то мы видим что для общего случая конструктор D::D написан неправильно.

То, что D::D работает не с любым корректно определенным классом C, а только с некоторым конкретным - плохо. Собственно, вопрос был - "правда ли, что так делать плохо". С моей точки зрения - да, плохо, потому что класс D написан неправильно, и не будет работать с другим C, даже если тот C будет определен корректно.

gzh
()
Ответ на: комментарий от yz

Еще раз, другими словами. Вопрос был - "А так правда плохо делать?". Вы без нужды связали два своих класса, С и D, связью, гораздо более жесткой чем это необходимо. Это плохо. Почему: когда кто-нибудь - не Вы - через год изменит реализацию C, и от этого совершенно неожиданно для него в совершенно другом месте рванет код, в котором используется D, - это будет Ваша вина.

gzh
()
Ответ на: комментарий от gzh

В конструкторе C я напишу комментарий, типа "нефиг юзать эту ссылку!" :-)

yz
() автор топика
Ответ на: комментарий от gzh

> Почему: когда кто-нибудь - не Вы - через год изменит реализацию C, и от этого совершенно неожиданно для него в совершенно другом месте рванет код, в котором используется D, - это будет Ваша вина.

баян:

> Только с точки зрения дизайна - получается говнясто. В базовом классе прийдется помнить, что ссылку нельзя использовать, из-за особенностей реализации класса-предка. fmj (*) (04.08.2008 19:13:51)

dilmah ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.