Здравствуйте, Erop, Вы писали:
E>Здравствуйте, Evgeniy13, Вы писали:
E>>- Наследование вместо агрегации (не нужно лишний раз обращаться к переменной). Но в этом случае очевидно должно быть защищенное наследование. E>>- Наследование как наследования реализации (опять-таки должно быть защищенное наследование)
E>А почему protected, а не private?
Не я имел в виду на самом деле любое наследование кроме открытого. Что конкретно (protected или private) зависит от конкретного дизайна.
Не все в этом мире можно выразить с помощью нулей и единиц...
Здравствуйте, Roman Odaisky, Вы писали:
RO>Есть вот такой баян, запрещающий наследование от определенного класса: RO>
RO>class Final;
RO>class FinalHelper
RO>{
RO>friend class Final;
RO>private:
RO> FinalHelper() { }
RO>};
RO>class Final: public SomeInterface, virtual private FinalHelper
RO>{
RO> . . .
RO>};
RO>class Error: public Final // не-не
RO>{
RO> . . .
RO>};
RO>
RO>Здесь конструктор FinalHelper должен будет быть вызван из конструктора Error (если бы наследование было невиртуальным, этот конструктор вызывался бы из конструктора Final), а Error не имеет к нему доступа, потому что он private.
Крайне сомнительно что FinalHelper позовется. Во всяком случае онлайн компиляторы http://www.comeaucomputing.com/tryitout/ и http://www.interstron.ru/eng/text.asp?id=3792 сожрали это без вопросов
Ну типа FinalHelper не будет конструироваться, что ли?
Попробуй создать объект выведенного класса...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Попробуй создать объект выведенного класса...
Попробовал — действительно не создаются обьекты. Но FinalHelper в Error нужен ли? В принципе его могли позвать и из Final.
Чтоб скомпилировать создание обьекта Error нужно и friend class Error; и friend class Final; . Но ведь зовется то только один конструктор
Здравствуйте, Programador, Вы писали:
P>Чтоб скомпилировать создание обьекта Error нужно и friend class Error; и friend class Final; . Но ведь зовется то только один конструктор
Конструктор виртуальной базы зовётся из самого выведенного объекта. Если не понятно почему это так, то могу объяснить (глупый ответ "по стандарту" )
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Конструктор виртуальной базы зовётся из самого выведенного объекта. Если не понятно почему это так, то могу объяснить (глупый ответ "по стандарту" )
Оба friend нужны. Но в одном из классов конструктор не нужен. Вопрос или в стандарте сказано проверить сначала на даступность, а потом на нужность? Или они тексты друг у друга воруют
class Final;
class FinalHelper
{
friend class Error;
friend class Final;private:
FinalHelper() { }
};
class Final: virtual private FinalHelper
{
};
class Error: public Final // не-не
{
};
Error ee;
Здравствуйте, Erop, Вы писали:
E>Мало ли зачем? Скажем тебя может заинтересовать сколько мест для рассадки гостей есть в комнате, или сколько для раскладывания на ночлег. Соответсвенно нужны разные свойства.
Таким образом, ты ведешь речь о сферической лошади в вакууме, никому на практике не нужной.
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Здравствуйте, McSeem2, Вы писали:
MS>Таким образом, ты ведешь речь о сферической лошади в вакууме, никому на практике не нужной.
Таким образом я не хочу описывать реальную сложную задачу, где ООП иерархии имеют смысл. Конечно в мегапродукте "Hellow World" без наследования обычно можно легко обойтись
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Programador, Вы писали:
P>Оба friend нужны. Но в одном из классов конструктор не нужен. Вопрос или в стандарте сказано проверить сначала на даступность, а потом на нужность? Или они тексты друг у друга воруют
Как-то не понятно что бы обозначало выделенное
По стандарту непосредственно из конструктора самого выведенного класса зовутся конструкторы всех виртуальных баз. Соответсвенно их нужно позвать и для этого нужен доступ.
Или ты имеешь в виду, что конструктор FinalHelper ничего не делает?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Как-то не понятно что бы обозначало выделенное E>По стандарту непосредственно из конструктора самого выведенного класса зовутся конструкторы всех виртуальных баз. Соответсвенно их нужно позвать и для этого нужен доступ.
Но тогда он не зовется из Final , а без friend class Final; не компилируется.
Здравствуйте, McSeem2, Вы писали:
E>>Мало ли зачем? Скажем тебя может заинтересовать сколько мест для рассадки гостей есть в комнате, или сколько для раскладывания на ночлег. Соответсвенно нужны разные свойства.
MS>Таким образом, ты ведешь речь о сферической лошади в вакууме, никому на практике не нужной.
так это в идеальной задаче нужно чтото одно, а в реальной сегодня одно, завтра другое и то что позавчера не перестает быть нужно
Здравствуйте, Programador, Вы писали:
P>Но тогда он не зовется из Final , а без friend class Final; не компилируется.
Ну он должен таки иметь возможность позваться.
Груба говоря, все виртуальные наследники, даже и непрямые, должны действовть так: "Если виртуальная база ещё не создана -- создать"
Ты же не знаешь из какого контекста это всё позовут.
Вот ты запихнёшь это всё в библиотеку, скомпилишь и отдашь, а пользователи захотят и позовут copy-constructor Final от Error...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Груба говоря, все виртуальные наследники, даже и непрямые, должны действовть так: "Если виртуальная база ещё не создана -- создать"
Тоесть "не создана" определяется в рунтайм? — но это уже вопрос скорее топикстартеру
Здравствуйте, Programador, Вы писали:
MS>>Таким образом, ты ведешь речь о сферической лошади в вакууме, никому на практике не нужной. P>так это в идеальной задаче нужно чтото одно, а в реальной сегодня одно, завтра другое и то что позавчера не перестает быть нужно
Ну вот и ответ на вопрос. Надо обеспечить нормальную полиморфность с виртуальными функциями. А если их нет, то зачем тогда наследование?
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Re[8]: protected vs private
От:
Аноним
Дата:
10.09.07 14:56
Оценка:
Здравствуйте, Roman Odaisky, Вы писали:
RO>Я пока знаю только одно приличное применение protected, и то оно там не используется: деструкторы std::unary_function, std::iterator и прочих невиртуальных интерфейсов.
я тебе еще одно подскажу. Есть класс для работы с http протоколом и класс для работы с http протоколом, который наследует первый класс. Медод int sk нужен и тому и другому классу, делаем его protected.
Можно делать всё публик, но тогда зачем юзать классы?, юзать структуры!, строчку public писать не нужно будет, и на одну строку будет кода меньше — но это выглядит не профессионально. У меня привычка закрывать от юзера данные, которые ему не нужно знать, а то он в еще в целях экономии памяти запишит, что — нибуть туда, ну или мало ли.
Читать профессиональный код намного приятней.
А protected'ить от самого себя данные — не вижу смысла, я то знаю какой метод для чего предназначен.
И еще мне одна идея пришла в голову, почему не нужно открывать все члены. Наверно есть ide или будут, которые не будут выдавать в списке членов, члены, которые закрыты, когда программист будет вводить оператор расширения области видимости.
Re[9]: protected vs private
От:
Аноним
Дата:
10.09.07 15:14
Оценка:
McSeem2 метод, который заменяется в наследнике, не всегда выгодно делать виртуальной, например когда ты вызываешь метод не через указательна на базовый класс, а через указательно на этот класс
Здравствуйте, Roman Odaisky, Вы писали:
RO>Здравствуйте, Аноним, Вы писали:
А>>Кстати про виртуальное наследование: А>>давно интересуют примеры его использования в реальных программах.
RO>Есть вот такой баян, запрещающий наследование от определенного класса: RO>
RO>class Final;
RO>class FinalHelper
RO>{
RO>friend class Final;
RO>private:
RO> FinalHelper() { }
RO>};
RO>class Final: public SomeInterface, virtual private FinalHelper
RO>{
RO> . . .
RO>};
RO>class Error: public Final // не-не
RO>{
RO> . . .
RO>};
RO>
RO>Здесь конструктор FinalHelper должен будет быть вызван из конструктора Error (если бы наследование было невиртуальным, этот конструктор вызывался бы из конструктора Final), а Error не имеет к нему доступа, потому что он private.
Кстати где-то читал, что данную конструкцию нельзя создать на шаблонах, т.к. конструкция
template<typename T> class a{ friend class T;}
не соответствует стандарту. Вот пример который вроде не противоречит стандарту:
template<typename T>
struct type2type{ typedef T type; };
template<typename T>
class final;
template<typename T>
class final_helper
{
friend class type2type< final<T> >::type;
friend class type2type< T >::type;
private:
final_helper(){};
};
template<typename T>
class final: virtual public final_helper< T >{};
class a: final<a>{};
class b: public a{};
void main()
{
a aa;
b bb; // error: К сожалению ошибку выдаст только при попытке создать объект, но все же лучше чем ничего
}
Здравствуйте, Programador, Вы писали:
P>Тоесть "не создана" определяется в рунтайм? — но это уже вопрос скорее топикстартеру
Нет, такое поведение стандартом, конечно, не навязывается. Напрмиер, может быть скрытый аргумент конструктора, или дополнительная точка входа в конструктор (для конструирования наиболее выведенного объекта и для конструирования базы)
Но в любом случае Каждый из конструкторов может быть вызван из более поздно написанного кода из другой единицы трансляции...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Аноним, Вы писали:
А>А protected'ить от самого себя данные — не вижу смысла, я то знаю какой метод для чего предназначен.
Через месяц/год ты уже понятия не будешь иметь, какой метод для чего нужен.
Не говоря уже о другом человеке, который, возможно, будет поддерживать твой код.
А кодирование в стиле "все паблик" применимо только к проектам типа "сдал и забыл" (курсовая, например).
You will always get what you always got
If you always do what you always did
Re[4]: Виртуальное наследование
От:
Аноним
Дата:
12.09.07 16:26
Оценка:
Здравствуйте, s_viy, Вы писали:
>Кстати где-то читал, что данную конструкцию нельзя создать на шаблонах, т.к. конструкция
template<typename T> class a{ friend class T;}
не соответствует стандарту. Вот пример который вроде не противоречит стандарту:
>template<typename T>
>struct type2type{ typedef T type; };
>template<typename T>
>class final;
>template<typename T>
>class final_helper
>{
> friend class type2type< final<T> >::type;
> friend class type2type< T >::type;
>private:
> final_helper(){};
>};
>template<typename T>
>class final: virtual public final_helper< T >{};
>class a: final<a>{};
>class b: public a{};
>void main()
>{
> a aa;
> b bb; // error: К сожалению ошибку выдаст только при попытке создать объект, но все же лучше чем ничего
>}
>