Re[12]: Почему конструкторы не наследуются?
От: Павел Кузнецов  
Дата: 26.07.05 14:15
Оценка: 4 (1) +2
VladD2,

V> Но объявлять костркуторы тоже не дело. Можно было бы хоть как-то

V> облегчить жизнь программисту. Ну, там некий атрибут ввести, мол у этого
V> класс таки можно наследовать конструкторы. Или еще что.

Все проще: для предоставления утилит к существующему классу не нужно от него
наследоваться. Нужно просто предоставить утилиты. В C++ для этого есть "свободные"
функции. В C# можно сделать класс со статическими методами. И не будет никаких
проблем со скрытыми конструкторами и т.п.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[12]: Почему конструкторы не наследуются?
От: VladD2 Российская Империя www.nemerle.org
Дата: 26.07.05 15:10
Оценка: 1 (1) +2
Здравствуйте, Павел Кузнецов, Вы писали:


ПК>Виртуальных в C++ из-за отсутствия декларатора new -- может. В итоге добавлять виртуальные функции

ПК>нужно очень осторожно. Но это немного другой случай: виртуальную функцию добавляют именно для того,
ПК>чтобы она появилась в наследниках. Конструкторы, все-таки, на неком особом положении по сравнению
ПК>с остальными функциями: они устанавливают инварианты класса, создавая класс из "сырой" памяти.

Фиг с ними с виртуальными. Но я никак не пойму чем отличается добавление конструкторов и обычных методов. Наследники могут оказаться не готовы как к тем, так и к другим.
... << RSDN@Home 1.2.0 alpha rev. 591>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Почему конструкторы не наследуются?
От: dshe  
Дата: 25.07.05 10:44
Оценка: +3
Здравствуйте, Дарней, Вы писали:

Д>Здравствуйте, AndrewVK, Вы писали:


AVK>>Здравствуйте, SilverCloud, Вы писали:


SC>>>В чём глубокий смысл сабжа в C#?


AVK>>Одна из причин — необходимость убирать базовые конструкторы.


Д>А когда возникает такая необходимость? Мне в голову ни один пример не приходит.

Д>Но даже если такая необходимость вдруг возникнет (в чем я лично сомневаюсь), никто не мешает перекрыть конструктор и сделать его protected или private.

Необходимость возникает когда в наследнике добавляется поле, которое должно быть инициализировано (в конструкторе) ненулевым значением. Так называемое "наследование конструкторов" скорее всего приведет к тому, что у класса-наследника будет много конструкторов, унаследованных от предков самой разной близости, которые не инициализируют объект полностью. А это чревато ошибками. На мой взгляд, гораздо проще (и безопаснее) явно объявить конструктор, в котором просто вызвать base, чем скрывать за private или protected лишние конструкторы.
--
Дмитро
Re[7]: Почему конструкторы не наследуются?
От: dshe  
Дата: 25.07.05 11:38
Оценка: +2 -1
Здравствуйте, Дарней, Вы писали:

Д>Здравствуйте, AndrewVK, Вы писали:


Д>И вот ради такого редкого случая заставлять всех писать кучу ненужного кода?


Для того, чтобы оценить какие случаи редкие, а какие нет, можно посчитать сколько раз конструктор определяется только для того, чтобы вызвать базовый (с теми же параметрами). Я думаю, что наоборот, необходимость в "наследовании конструкторов" возникает весьма нечасто.
--
Дмитро
Re[2]: Почему конструкторы не наследуются?
От: jazzer Россия Skype: enerjazzer
Дата: 25.07.05 15:06
Оценка: +3
Здравствуйте, Oyster, Вы писали:

O> при добавлении нового конструктора в базовом классе он чудесным образом появится во всех наследниках, как в C++.


Ничего подобного в С++ нет.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[10]: Почему конструкторы не наследуются?
От: vdimas Россия  
Дата: 12.08.05 08:13
Оценка: 2 (2)
Здравствуйте, VladD2, Вы писали:

VD>Такое ощущение, что ты мои слова не читашь.


VD>>>Ну, и в чем проблема? Если полей нет или все они инициализируются по месту, то что может помешать наследованию конструктора?


V>>Если бы конструкторы наследовались, то мы получили бы грабли в виде возможности неккоректного создания Derived.


VD>А если все же полей нет, или все инициализируется по месту?


Я хорошо читаю, но не представляю, как это все констроллировать в реальной программе. Слишком опасным было бы наличие такого правила в неявном виде. Необходимо ср-во явного задания ситуации "наследования" кострукторов.

V>> Intellisense дает нам подсказку двух конструкторов, бери на здоровье. Лекарство состояло бы в принудительном переопределении базовых конструкторов как private. Тогда бы нарушалась инкапсуляция базового класса, ибо любые незначительные изменения в нем (скажем — ввод нового конструктора) потребовал бы доработки ВСЕХ наследников. И жили бы мы весело


VD>Да вариантов придумать можно много. Плохо что выбран был самый примитивный.


Да это первое, что приходит в голову. Если подобная опция будет нам дана неявно (не дай бог), мы устанем "закрывать" базовые конструкторы.

Ведь все равно непонятно, что делать в твоем случае, когда у нас дополнительных полей нет в Derived или все они инициализированы по месту, но при этом есть хотя бы один "наш" конструктор. Простейшая ситуация — при создании экземпляра мы хотим его зарегистрировать где-то, или подать как параметр объект, к которому он подпишется на события и т.д. и т.п. Ведь это весьма частовстречающийся сценарий, когда у наследника переопределен только конструктор, в котором и выполняются некие целевые действия. (Узлы синтаксического дерева — один из примеров).

Так вот, что делать компилятору в этом случае? Оставлять видимыми другие конструкторы вместе с вновь определенными или нет??? Я знаю как минимум одно место, где было бы неплохо оставлять — это наследники типизированных коллекций (и то не всегда).

Я как бы за то, чтобы иметь директиву, например, using в самом классе, но с определенным синтаксисом для конструктора. Что-то типа так:

class DerivedClass : BaseClass {
  using base(...);  // сделать доступными ВСЕ базовые конструкторы, не пересекающиеся по сигнатурам с собственными

  using base();             // сделать доступными только определенные сигнатуры.
  using base(Type1, Type2);
}


Код автоинициализированных полей компилятор вставляет в начало КАЖОГО конструктора и сейчас, т.е. он и так участвует в догенерировании кода конструкторов. Резюмируя все это — фича конечно неплохая, но только в случае явного управления ею.
Re: Почему конструкторы не наследуются?
От: VladD2 Российская Империя www.nemerle.org
Дата: 24.07.05 08:33
Оценка: 1 (1) +1
Здравствуйте, SilverCloud, Вы писали:

SC>В чём глубокий смысл сабжа в C#?


Думаю, по глупости содрали поведение с С++. Наверно найдется много "умных" обоснований почему это так, но я сам себя не раз ловил на мысли, что с удовольствием бы воспользовался кострукторами базовых клссов.
... << RSDN@Home 1.2.0 alpha rev. 591>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Почему конструкторы не наследуются?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 25.07.05 10:03
Оценка: 1 (1) :)
Здравствуйте, SilverCloud, Вы писали:

SC>В чём глубокий смысл сабжа в C#?


Одна из причин — необходимость убирать базовые конструкторы.
... << RSDN@Home 1.2.0 alpha rev. 594>>
AVK Blog
Re[6]: Почему конструкторы не наследуются?
От: dshe  
Дата: 25.07.05 15:44
Оценка: -2
Здравствуйте, VladD2, Вы писали:

AS>> Если нужна такая фича, проще перегрузить конструтор, а в нем написать super(). И все, и никаких проблем


VD>Помтоу что это море никому не нужного кода. Вот представь... Создал я реализацию некой коллекции. Причем в рассчете на то, что напрямую ее создавать никто не будет, а на против, будут порождать он нее наследников. Так вот в этой коллекции есть, предположим, 20 конструкторов. Их все прейдется описать в наследнике. Да еще не ошибиться.


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

Одно из предназначений конструктора -- инициализировать поля объекта. Поэтому часто бывает достаточно одного "главного" конструктора (возможно с большим количеством аргументов), который инициализирует все поля. Однако конструктор с большим количеством аргументов использовать неудобно, поэтому и создаются дополнительные конструкторы (с меньшим количеством аргументов), которые некоторые поля инициализируют некими умолчательными значениями. Полагаю, что твой класс для наследования с 20 конструкторами ничего не потеряет если будет иметь всего один "главный" конструктор. А на остальных конструкторах данного класса можно было бы и сэкономить.

Что касается наследников, то на их конструкторах сэкономить, в общем случае, уже не получится, поскольку им в любом случае надо инициализировать свои поля. "Наследование конструкторов" могло бы быть безопасным лишь в том случае, если бы наследник не добавлял своих полей; либо явно указывал, что свои поля он инициализировать значениями, отличными от умолчательных, не собирается; либо явно переопределял все "унаследованные" конструкторы.
--
Дмитро
Re[8]: Почему конструкторы не наследуются?
От: Sinclair Россия https://github.com/evilguest/
Дата: 29.07.05 06:24
Оценка: 26 (1)
Здравствуйте, AndrewVK, Вы писали:
AVK>Да, так конечно проблем намного меньше. С другой стороны и ситуация такая нужна бывает нечасто (хотя, опять же, вопрос проектирования библиотек).
AVK>А вобще, если немножко пофантазировать, то можно отказаться от классического наследования, оставив реализацию интерфейсов (и множественное наследование их между собой) и добавив миксины (как, кстати, правильно по-русски, подмешивания?).
примеси
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[7]: Почему конструкторы не наследуются?
От: Павел Кузнецов  
Дата: 25.07.05 12:31
Оценка: 4 (1)
Дарней,

AVK>> Смысл в том, что алгоритмы Derived рассчитаны на то, что алгоритмы

AVK>> Base будут работать всегда с флажком true. protected конструктор
AVK>> делать нельзя, поскольку класс Base может быть самоценен.

Д> И вот ради такого редкого случая заставлять всех писать кучу ненужного

Д> кода? Который, к тому же, прекрасно решается другими средствами.

Какими средствами? Т.е., если инвариантом Derived является то, что Base
проинициализирован someFlag = true, то как это обеспечить при открытом
конструкторе Base(bool)?

Варианты явным образом закрывать конструкторы подходят не вполне, т.к.
при добавлении базовых классов необходимо будет просматривать всех
наследников, что в общем случае сделать нереально.

Имхо, то же самое относится и к обычным функциям, но почему-то в C# этот
вопрос решили по-другому...
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[6]: Почему конструкторы не наследуются?
От: VladD2 Российская Империя www.nemerle.org
Дата: 26.07.05 13:31
Оценка: 3 (1)
Здравствуйте, dshe, Вы писали:

Кстати, проблему можно было бы решить так как это сделано в Дельфи. То есть разрешать только повышать уровень видимости. Тогда можно было бы создавать промежуточные классы с, предполжим, protected свойствами и делать их видимыми в наследниках.
... << RSDN@Home 1.2.0 alpha rev. 591>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[10]: Почему конструкторы не наследуются?
От: Павел Кузнецов  
Дата: 26.07.05 13:34
Оценка: 3 (1)
VladD2,

V> Что до безопасности, то отсуствие новых полей не имеющих инициализации

V> по умолчанию более чем позволяет безопасно наследовать конструкторы.

Не позволяет, т.к. инварианты могут выражаться не только в значении новых полей,
но и в комбинации полей базовых классов.

Возьми для примера тот же случай наследования немодифицируемого Square
от немодифицируемого Rectangle.
class Rectangle
{
  public Rectangle( int width, int height );

  public int width();
  public int height();

  private int width_;
  private int height_;
};

class Square : Rectangle
{
  public Square( int size );
};

Хотя случай и близок к паталогическому, тем не менее, явной ошибки не содержит.

В случае же если конструктор базового класса будет "унаследован" по правилам,
аналогичным правилам наследования функций в C#, то Square можно будет создать
в невалидном состоянии, с шириной не равной высоте.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[2]: Почему конструкторы не наследуются?
От: VladD2 Российская Империя www.nemerle.org
Дата: 25.07.05 14:58
Оценка: 1 (1)
Здравствуйте, AndrewVK, Вы писали:

SC>>В чём глубокий смысл сабжа в C#?


AVK>Одна из причин — необходимость убирать базовые конструкторы.


Лучше бы решили проблему скрытия методов в наследнике. А то нобходимость скрывать конструкторы возникает не чаще чем обычные методы. В общем, не логично.
... << RSDN@Home 1.2.0 alpha rev. 591>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Почему конструкторы не наследуются?
От: Дарней Россия  
Дата: 26.07.05 08:15
Оценка: 1 (1)
Здравствуйте, dshe, Вы писали:

D>А чем тогда NotSupportedException не подошел? Тоже способ дать понять, что хотя метод и можно вызвать, но лучше этого не делать.


Тем, что он не срабатывает во время компиляции.

D>в принципе использоваться не могут.


С помощью отражения, unsafe и/или иных трюков можно использовать любые скрытые методы и поля, если у программиста возникнет такое желание.
Поэтому отложим вакуумных сфероконей в сторону и поговорим о более приземленных вещах. Например, защите от нечаянной ощибки. Сокрытие методов эту задачу решает — этого вполне достаточно.

D>По поводу Array.IList.Add Method: то, что метод всегда выбрасывает исключение -- не образец для подражания.


В данном случае это скорее кривой дизайн. Тем не менее, такая необходимость бывает, и нередко. Сейчас ее можно решить только инкапсуляцией и копи-пейстом гор кода, что не есть хорошо — и к тому же, все равно не дает никаких гарантий.
Всех излечит, исцелит
добрый Ctrl+Alt+Delete
Re[13]: Почему конструкторы не наследуются?
От: Павел Кузнецов  
Дата: 26.07.05 14:25
Оценка: 1 (1)
P.S.

ПК> Все проще: для предоставления утилит к существующему классу не нужно от

ПК> него наследоваться. Нужно просто предоставить утилиты. В C++ для этого
ПК> есть "свободные" функции. В C# можно сделать класс со статическими
ПК> методами. И не будет никаких проблем со скрытыми конструкторами и т.п.

А для тех редких случаев, где, действительно, имеет смысл наследоваться
не изменяя инварианты, затрагиваемые конструкторами, в C++ обсуждается введение
явной возможности наследовать конструкторы базового класса:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1583.pdf
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[5]: Почему конструкторы не наследуются?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 27.07.05 08:29
Оценка: 1 (1)
Здравствуйте, Дарней, Вы писали:

Д>Чтобы не приходилось писать в документации вот так:

Д>

Д>Array.IList.Add Method
Д>Implements IList.Add. Always throws NotSupportedException.


Во-первых этот метод и так скрытый и в публичном интерфейсе массивов отсутствует. Проявляется он только когда явно приводим массив к IList (в котором этот метод присутствует по определению).
Во-вторых это следствие ошибки проектирования интерфейсов коллекций. Если бы вместо IList было два интерфейса — IIndexCollection и IMutableCollection, то проблемы такой не было бы.

Д>А что здесь парадоксального? Программист просто дает понять, что хотя метод и можно вызвать, но лучше этого не делать.


Явная реализация интерфейсов неплохо с этим справляется.
... << RSDN@Home 1.2.0 alpha rev. 596>>
AVK Blog
Re[3]: Почему конструкторы не наследуются?
От: dshe  
Дата: 24.07.05 19:08
Оценка: +1
Здравствуйте, AlSy, Вы писали:

VD>>Думаю, по глупости содрали поведение с С++. Наверно найдется много "умных" обоснований почему это так, но я сам себя не раз ловил на мысли, что с удовольствием бы воспользовался кострукторами базовых клссов.


AS>Я вообще-то из братии Java... Тем не менее, слабо верится, что в C# нету super();...


он у них называется base.

вообше-то, насколько я понял, речь идет не о возможности вызвать конструктор базового класса из конструктора наследника, а возможности создавать экземпляры класса-наследника извне, пользуясь конструктором, который не определен явно в данном классе, но который сгенерен компилятором ("унаследован") по конструктору базового класса с той же самой сигнатурой.
--
Дмитро
Re[4]: Почему конструкторы не наследуются?
От: AlSy Украина  
Дата: 25.07.05 10:11
Оценка: +1
Здравствуйте, dshe, Вы писали:

D>Здравствуйте, AlSy, Вы писали:


VD>>>Думаю, по глупости содрали поведение с С++. Наверно найдется много "умных" обоснований почему это так, но я сам себя не раз ловил на мысли, что с удовольствием бы воспользовался кострукторами базовых клссов.


AS>>Я вообще-то из братии Java... Тем не менее, слабо верится, что в C# нету super();...


D>он у них называется base.


D>вообше-то, насколько я понял, речь идет не о возможности вызвать конструктор базового класса из конструктора наследника, а возможности создавать экземпляры класса-наследника извне, пользуясь конструктором, который не определен явно в данном классе, но который сгенерен компилятором ("унаследован") по конструктору базового класса с той же самой сигнатурой.


Ну это как-то не хорошо... Что ж мне, если я не хочу, чтобы конструктор наследовался таким образом, обязательно перегружать его в наследнике? ИМХО, неправильно, да и по идее породит море логических ошибок. Если нужна такая фича, проще перегрузить конструтор, а в нем написать super(). И все, и никаких проблем
Все говорят, что я садист, но на самом деле я добрый. У меня сердце ребенка. Вот оно — в банке с формалином.
Re[5]: Почему конструкторы не наследуются?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 25.07.05 11:17
Оценка: +1
Здравствуйте, Дарней, Вы писали:

AVK>>Очень странно. Такое довольно часто встречается.

AVK>>
AVK>>class Base
AVK>>{
AVK>>    public Base(bool someFlag)
AVK>>    {}
AVK>>}

AVK>>class Derived
AVK>>{
AVK>>    public Derived() : base(true)
AVK>>    {}
AVK>>}
AVK>>


Д>Ну а смысл то в чем? Если Base(bool someFlag) используется для каких-то внутренних целей данной иерархии, то разумнее сделать его protected.


Смысл в том, что алгоритмы Derived рассчитаны на то, что алгоритмы Base будут работать всегда с флажком true. protected конструктор делать нельзя, поскольку класс Base может быть самоценен.



AVK>>Что такое перекрыть конструктор? Такого понятия в C# нет.


Д>Я думал, несложно догадаться.


И о чем я должен догадаться? Что там физически должно происходить?
... << RSDN@Home 1.2.0 alpha rev. 594>>
AVK Blog
Re[8]: Почему конструкторы не наследуются?
От: Дарней Россия  
Дата: 25.07.05 11:56
Оценка: +1
Здравствуйте, dshe, Вы писали:

D>Я думаю, что наоборот, необходимость в "наследовании конструкторов" возникает весьма нечасто.


Если такую тему регулярно поднимают — значит, часто.
Всех излечит, исцелит
добрый Ctrl+Alt+Delete
Re[4]: Почему конструкторы не наследуются?
От: VladD2 Российская Империя www.nemerle.org
Дата: 25.07.05 14:58
Оценка: +1
Здравствуйте, dshe, Вы писали:

D>Необходимость возникает когда в наследнике добавляется поле, которое должно быть инициализировано (в конструкторе) ненулевым значением. Так называемое "наследование конструкторов" скорее всего приведет к тому, что у класса-наследника будет много конструкторов, унаследованных от предков самой разной близости, которые не инициализируют объект полностью. А это чревато ошибками. На мой взгляд, гораздо проще (и безопаснее) явно объявить конструктор, в котором просто вызвать base, чем скрывать за private или protected лишние конструкторы.


Ну, и почему не поступать так же как с конструкторами без параметров? Ну, наследовать конструкторы если в наследнике они не определены явно.

А еще лучше позволить вручную скрывать любые методы.
... << RSDN@Home 1.2.0 alpha rev. 591>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Почему конструкторы не наследуются?
От: VladD2 Российская Империя www.nemerle.org
Дата: 26.07.05 02:44
Оценка: +1
Здравствуйте, dshe, Вы писали:

D>Создавать 20 конструкторов в классе, предназначенном исключительно для наследования от него, с твоей стороны, -- это плыть против течения. Тем более, что ты прекрасно знаешь, что кому-то (может быть и тебе) придется в наследниках их все определять заново.


Это жизнь. Ну, нужны эти 20 конструкторов. Мало ил как объект будет инициализироваться?

D>Одно из предназначений конструктора -- инициализировать поля объекта. Поэтому часто бывает достаточно одного "главного" конструктора (возможно с большим количеством аргументов), который инициализирует все поля.


"Часто", "бывает"... это не те категории. Бывает по разному. Бывает, что нужно унаследовать конструкторы. Ну, не ввел я ни одного нового поля. Так зачем же мне переоеределяь все 20 конструкторов? А ведь с теми самыми базовыми классами коллекций так и бывает.

D> Однако конструктор с большим количеством аргументов использовать неудобно, поэтому и создаются дополнительные конструкторы (с меньшим количеством аргументов), которые некоторые поля инициализируют некими умолчательными значениями. Полагаю, что твой класс для наследования с 20 конструкторами ничего не потеряет если будет иметь всего один "главный" конструктор. А на остальных конструкторах данного класса можно было бы и сэкономить.


Это экономия на пользователях твоего класса. В общем, плохое решение.

D>Что касается наследников, то на их конструкторах сэкономить, в общем случае, уже не получится, поскольку им в любом случае надо инициализировать свои поля.


Предположим, нет полей. Хотя я уже повторяюсь.

D> "Наследование конструкторов" могло бы быть безопасным лишь в том случае, если бы наследник не добавлял своих полей; либо явно указывал, что свои поля он инициализировать значениями, отличными от умолчательных, не собирается; либо явно переопределял все "унаследованные" конструкторы.


Ну, и в чем проблема? Если полей нет или все они инициализируются по месту, то что может помешать наследованию конструктора?

ЗЫ

В общем, это все попытки скрыть явный прощет в дизайне языков.
... << RSDN@Home 1.2.0 alpha rev. 591>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Почему конструкторы не наследуются?
От: Дарней Россия  
Дата: 26.07.05 07:40
Оценка: :)
Здравствуйте, dshe, Вы писали:

D>А зачем может понадобиться скрывать методы в наследнике? Если наследник не реализует весь тот интерфейс, который он унаследовал, то он может и не должен быть наследником? поскольку в этом случае явно нарушается LSP.


Чтобы не приходилось писать в документации вот так:

Array.IList.Add Method
Implements IList.Add. Always throws NotSupportedException.


D>Что приводит к следующему парадоксу, на мой взгляд.

D>
D>B *b = new B();
b->>f(); // так нельзя -- ошибка компиляции
D>((A *) b)->f(); // а так уже можно
D>

D>Получается, что вполне легальными средствами можно доступиться к скрытому методу.

А что здесь парадоксального? Программист просто дает понять, что хотя метод и можно вызвать, но лучше этого не делать.
Всех излечит, исцелит
добрый Ctrl+Alt+Delete
Re[5]: Почему конструкторы не наследуются?
От: dshe  
Дата: 26.07.05 08:06
Оценка: :)
Здравствуйте, Дарней, Вы писали:

Д>Здравствуйте, dshe, Вы писали:


D>>А зачем может понадобиться скрывать методы в наследнике? Если наследник не реализует весь тот интерфейс, который он унаследовал, то он может и не должен быть наследником? поскольку в этом случае явно нарушается LSP.


Д>Чтобы не приходилось писать в документации вот так:

Д>

Д>Array.IList.Add Method
Д>Implements IList.Add. Always throws NotSupportedException.


D>>Что приводит к следующему парадоксу, на мой взгляд.

D>>
D>>B *b = new B();
b->>>f(); // так нельзя -- ошибка компиляции
D>>((A *) b)->f(); // а так уже можно
D>>

D>>Получается, что вполне легальными средствами можно доступиться к скрытому методу.

Д>А что здесь парадоксального? Программист просто дает понять, что хотя метод и можно вызвать, но лучше этого не делать.


А чем тогда NotSupportedException не подошел? Тоже способ дать понять, что хотя метод и можно вызвать, но лучше этого не делать.

Насколько я понял, возможность скрывать методы в наследнике подразумевает проверки на этапе компиляции, что скрытые методы у класса-наследника не используются и в принципе использоваться не могут. Пример на C++ -- это повод показать, что полноценные проверки сделать невозможно; в C++, по крайней мере, это не получилось. Предложите свою модель.

По поводу Array.IList.Add Method: то, что метод всегда выбрасывает исключение -- не образец для подражания.
--
Дмитро
Re[13]: Почему конструкторы не наследуются?
От: dshe  
Дата: 26.07.05 08:26
Оценка: +1
Здравствуйте, Дарней, Вы писали:

Д>Здравствуйте, dshe, Вы писали:


D>>Как новый конструктор в базовом классе обеспечит инициализацию всех полей в тех наследниках, которые их, все-таки, несмотря ни на что, добавляют?


Д>Программисты, которые не ищут себе лишних проблем на задницу, делают это вот так:


calm down. различия во взглядах -- это не повод делать замечания, которые могут восприниматься как оскорбление.

Д>Программисты, которые не ищут себе лишних проблем на задницу, делают это вот так:

Д>
Д>class MyClass : BaseClass
Д>{
Д>  SomeClass someVar = new SomeClass();
Д>}
Д>

Д>Какие проблемы ты здесь видишь?

Для поля someVar (в данном примере), возможно не существует умолчательного значения, типа new SomeClass(). И во всех конструкторах (своих) оно инициализируется через параметр. Предсказать, какие конструкторы будут добавлены в базовый класс, для того, чтобы их скрыть заранее, либо должным образом переопределить -- задача нереальная.

D>>Так может новый конструтор в базовый класс добавлялся не просто так, а для того, чтобы он был унаследован и экземпляры классов-наследников могли создаваться с его помощью...


Д>Мне кажется, ты просто не понял, о чем идет речь.


Возможно. Объясни тогда другими словами. Я пытаюсь принять вашу позицию и найти в ней уязвимые места.
--
Дмитро
Re[13]: Почему конструкторы не наследуются?
От: VladD2 Российская Империя www.nemerle.org
Дата: 26.07.05 14:58
Оценка: +1
Здравствуйте, dshe, Вы писали:

D>Кстати, прекрасное применение твоему R#'у -- "наследовать" конструкторы если класс объявлен с аттрибутом, скажем, AddConstructorsFromSuperclass. При этом появление "лишних" конструкторов для программиста уже не будет незаметным (раз он собственноручно указывает такой аттрибут).


Такие примитивные вещи хорошо бы в язык встраивать. А не метапрограммированием решать.
... << RSDN@Home 1.2.0 alpha rev. 591>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Почему конструкторы не наследуются?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 27.07.05 08:29
Оценка: +1
Здравствуйте, VladD2, Вы писали:

VD>Лучше бы решили проблему скрытия методов в наследнике. А то нобходимость скрывать конструкторы возникает не чаще чем обычные методы. В общем, не логично.


ИМХО намного чаще, практически всегда. Просто ты обычно не обращаешь внимания на такие случаи, а вот когда ситуация обратная думаешь что так всегда и бывает. Исключение здесь составляют лишь конструкторы без параметров, но вот как раз для них в C# есть специальная синтаксическая затычка.
... << RSDN@Home 1.2.0 alpha rev. 596>>
AVK Blog
Re[5]: Почему конструкторы не наследуются?
От: Sinclair Россия https://github.com/evilguest/
Дата: 29.07.05 06:24
Оценка: +1
Здравствуйте, VladD2, Вы писали:
VD>А еще лучше позволить вручную скрывать любые методы.
Ну, instance метод не особенно-то скроешь, т.к. он будет доступен через приведение к предку. А вот конструкторы можно было бы и поскрывать.
Тут вопрос ровно в том, что чаще встречается — необходимость открыть конструктор предка или закрыть его.
Потому как для "открытия" и для закрытия потребуется совершенно одинаковый код. Единственное дополнение, которое я бы сделал для данного случая (сахар):
public class BaseClass
{
  public BaseClass(int capacity) 
    {
      ...
    }
}

public class DerivedClass: BaseClass
{
  public DerivedClass(int); 
    // эквивалентно следующему:
  public DerivedClass(int capacity): base(capacity)
    {
    }    
    
}

Это бы заметно сократило объем кода, который надо писать разработчику, особенно в случае длинных сигнатур конструкторов.
Можно было бы также добавить атрибут, который бы трактовался компилятором как инструкция генерировать конструктор потомка автоматически:

public class BaseClass
{
    [Inherit]
  public BaseClass(int capacity) 
    {
      ...
    }
    [Inherit]
    public BaseClass(IEnumerable source)
    {
    }
}

public class DerivedClass: BaseClass
{
  // подразумеваемые конструкторы, предоставленные компилятором:
//  public DerivedClass(int capacity): base(capacity)
//    {
//    }    
//    public DerivedClass(IEnumerable source): base(capacity)
//    {
//    }
}
public class DerivedClass2: BaseClass
{
  // явное сокрытие конструктора:
  private DerivedClass2(int);
    // частичное сокрытие и снятие атрибута Inherit:
    [Inherit(false)]
    protected DerivedClass2(IEnumerable source);
}
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[8]: Почему конструкторы не наследуются?
От: vdimas Россия  
Дата: 11.08.05 18:01
Оценка: -1
Здравствуйте, VladD2, Вы писали:


VD>Ну, и в чем проблема? Если полей нет или все они инициализируются по месту, то что может помешать наследованию конструктора?


То, что эту ситуацию никто не гарантирует. Например:
class Base {
    int i;

    public Base(int i) { this.i = i; }

}

class Derived : Base {
    double readonly d;
    
    public Derived(int i, double d) : base(i) {
        this.d = d;
    }
}


Если бы конструкторы наследовались, то мы получили бы грабли в виде возможности неккоректного создания Derived. Intellisense дает нам подсказку двух конструкторов, бери на здоровье. Лекарство состояло бы в принудительном переопределении базовых конструкторов как private. Тогда бы нарушалась инкапсуляция базового класса, ибо любые незначительные изменения в нем (скажем — ввод нового конструктора) потребовал бы доработки ВСЕХ наследников. И жили бы мы весело
Почему конструкторы не наследуются?
От: SilverCloud Россия http://rodonist.wordpress.com
Дата: 23.07.05 08:13
Оценка:
В чём глубокий смысл сабжа в C#?
Re: Почему конструкторы не наследуются?
От: Oyster Украина https://github.com/devoyster
Дата: 24.07.05 02:31
Оценка:
Здравствуйте, SilverCloud, Вы писали:

SC>В чём глубокий смысл сабжа в C#?


Вроде конструктор по умолчанию (без параметров) наследуется, если он не определён явно в наследнике. MSDN:

If a class contains no instance constructor declarations, a default instance constructor is automatically provided. That default constructor simply invokes the parameterless constructor of the direct base class.


А прочие... видимо, такое поведение было добавлено для лучшего контроля интерфейса класса (всегдя надо явно указывать все конструкторы класса кроме того, что по умолчанию) + видимо, решили, что так программисты будут допускать меньше ошибок "по недосмотру" (не будет возникать ситуаций, когда при добавлении нового конструктора в базовом классе он чудесным образом появится во всех наследниках, как в C++).

В общем-то, конструктор — не просто метод, конструктор инициализирует состояние объекта — логично, что базовый класс не может корректно проинициализировать своих наследников, поэтому каждый класс должен явно декларировать все свои конструкторы, даже если они просто вызывают base().

Всё изложенное выше — моё глубочайшее имхо.
Re[2]: Подумал
От: Oyster Украина https://github.com/devoyster
Дата: 24.07.05 03:51
Оценка:
Здравствуйте, Oyster, Вы писали:

[... skipped ...]

O>Вроде конструктор по умолчанию (без параметров) наследуется, если он не определён явно в наследнике. MSDN:


O>

O>If a class contains no instance constructor declarations, a default instance constructor is automatically provided. That default constructor simply invokes the parameterless constructor of the direct base class.


Конечно, это не наследование а генерация конструктора по умолчанию с вызовом конструктора предка, но поведение то же.
Re[2]: Почему конструкторы не наследуются?
От: AlSy Украина  
Дата: 24.07.05 16:25
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, SilverCloud, Вы писали:


SC>>В чём глубокий смысл сабжа в C#?


VD>Думаю, по глупости содрали поведение с С++. Наверно найдется много "умных" обоснований почему это так, но я сам себя не раз ловил на мысли, что с удовольствием бы воспользовался кострукторами базовых клссов.


Я вообще-то из братии Java... Тем не менее, слабо верится, что в C# нету super();...
Все говорят, что я садист, но на самом деле я добрый. У меня сердце ребенка. Вот оно — в банке с формалином.
Re[2]: Почему конструкторы не наследуются?
От: Дарней Россия  
Дата: 25.07.05 10:30
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, SilverCloud, Вы писали:


SC>>В чём глубокий смысл сабжа в C#?


AVK>Одна из причин — необходимость убирать базовые конструкторы.


А когда возникает такая необходимость? Мне в голову ни один пример не приходит.
Но даже если такая необходимость вдруг возникнет (в чем я лично сомневаюсь), никто не мешает перекрыть конструктор и сделать его protected или private.
Всех излечит, исцелит
добрый Ctrl+Alt+Delete
Re[3]: Почему конструкторы не наследуются?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 25.07.05 10:45
Оценка:
Здравствуйте, Дарней, Вы писали:

Д>А когда возникает такая необходимость? Мне в голову ни один пример не приходит.


Очень странно. Такое довольно часто встречается.
class Base
{
    public Base(bool someFlag)
    {}
}

class Derived
{
    public Derived() : base(true)
    {}
}


Д>Но даже если такая необходимость вдруг возникнет (в чем я лично сомневаюсь), никто не мешает перекрыть конструктор и сделать его protected или private.


Что такое перекрыть конструктор? Такого понятия в C# нет.
... << RSDN@Home 1.2.0 alpha rev. 594>>
AVK Blog
Re[4]: Почему конструкторы не наследуются?
От: Дарней Россия  
Дата: 25.07.05 10:53
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Очень странно. Такое довольно часто встречается.

AVK>
AVK>class Base
AVK>{
AVK>    public Base(bool someFlag)
AVK>    {}
AVK>}

AVK>class Derived
AVK>{
AVK>    public Derived() : base(true)
AVK>    {}
AVK>}
AVK>


Ну а смысл то в чем? Если Base(bool someFlag) используется для каких-то внутренних целей данной иерархии, то разумнее сделать его protected.
Почему Base(bool someFlag) должен обязательно быть виден для всех, а Derived(bool someFlag) ни в коем случае нет?

AVK>Что такое перекрыть конструктор? Такого понятия в C# нет.


Я думал, несложно догадаться.

        class Base
        {
            public Base(bool someFlag)
            {}
        }

        class Derived : Base
        {
            protected Derived(bool someFlag) : base(someFlag)
            {}

            public Derived() : base(true)
            {}
        }
Всех излечит, исцелит
добрый Ctrl+Alt+Delete
Re[6]: Почему конструкторы не наследуются?
От: Дарней Россия  
Дата: 25.07.05 11:29
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Смысл в том, что алгоритмы Derived рассчитаны на то, что алгоритмы Base будут работать всегда с флажком true. protected конструктор делать нельзя, поскольку класс Base может быть самоценен.


И вот ради такого редкого случая заставлять всех писать кучу ненужного кода?
Который, к тому же, прекрасно решается другими средствами.

AVK>И о чем я должен догадаться? Что там физически должно происходить?


о смысле слова "перекрыть". Иными словами, создать конструктор с такими же параметрами, но с другим спецификатором доступа.
Всех излечит, исцелит
добрый Ctrl+Alt+Delete
Re[5]: Почему конструкторы не наследуются?
От: VladD2 Российская Империя www.nemerle.org
Дата: 25.07.05 14:58
Оценка:
Здравствуйте, AlSy, Вы писали:

AS>Ну это как-то не хорошо... Что ж мне, если я не хочу, чтобы конструктор наследовался таким образом, обязательно перегружать его в наследнике? ИМХО, неправильно, да и по идее породит море логических ошибок.


Каких? Аргументы, плиз, в студию.

AS> Если нужна такая фича, проще перегрузить конструтор, а в нем написать super(). И все, и никаких проблем


Помтоу что это море никому не нужного кода. Вот представь... Создал я реализацию некой коллекции. Причем в рассчете на то, что напрямую ее создавать никто не будет, а на против, будут порождать он нее наследников. Так вот в этой коллекции есть, предположим, 20 конструкторов. Их все прейдется описать в наследнике. Да еще не ошибиться.
... << RSDN@Home 1.2.0 alpha rev. 591>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Почему конструкторы не наследуются?
От: dshe  
Дата: 25.07.05 15:57
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, dshe, Вы писали:


D>>Необходимость возникает когда в наследнике добавляется поле, которое должно быть инициализировано (в конструкторе) ненулевым значением. Так называемое "наследование конструкторов" скорее всего приведет к тому, что у класса-наследника будет много конструкторов, унаследованных от предков самой разной близости, которые не инициализируют объект полностью. А это чревато ошибками. На мой взгляд, гораздо проще (и безопаснее) явно объявить конструктор, в котором просто вызвать base, чем скрывать за private или protected лишние конструкторы.


VD>Ну, и почему не поступать так же как с конструкторами без параметров? Ну, наследовать конструкторы если в наследнике они не определены явно.


В смысле, наследовать конструкторы, если в наследнике ни один конструктор не определен явно? Наверняка существуют условия при которых "наследование конструкторов" безопасно. Но в любом случае, "лишние" конструкторы в наследнике не должны быть сюрпризом для программиста.
--
Дмитро
Re[3]: Почему конструкторы не наследуются?
От: Oyster Украина https://github.com/devoyster
Дата: 26.07.05 00:57
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Здравствуйте, Oyster, Вы писали:


O>> при добавлении нового конструктора в базовом классе он чудесным образом появится во всех наследниках, как в C++.


J>Ничего подобного в С++ нет.


Туплю — позабывал уже...
Re[8]: Почему конструкторы не наследуются?
От: Дарней Россия  
Дата: 26.07.05 03:43
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Какими средствами? Т.е., если инвариантом Derived является то, что Base

ПК>проинициализирован someFlag = true, то как это обеспечить при открытом
ПК>конструкторе Base(bool)?

ПК>Варианты явным образом закрывать конструкторы подходят не вполне, т.к.

ПК>при добавлении базовых классов необходимо будет просматривать всех
ПК>наследников, что в общем случае сделать нереально.

Добавлении базовых классов? Это как?
И зачем просматривать всех наследников? Ничего не пойму
Всех излечит, исцелит
добрый Ctrl+Alt+Delete
Re[9]: Почему конструкторы не наследуются?
От: Павел Кузнецов  
Дата: 26.07.05 06:29
Оценка:
Дарней,

ПК>> Варианты явным образом закрывать конструкторы подходят не вполне, т.к.

ПК>> при добавлении базовых классов необходимо будет просматривать всех
ПК>> наследников, что в общем случае сделать нереально.

Д> Добавлении базовых классов? Это как?


Оговорился. При добавлении конструкторов в базовых классах.

Д> И зачем просматривать всех наследников? Ничего не пойму


Чтобы убедиться, что их инварианты не нарушаются при добавлении нового конструктора в базе.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[3]: Почему конструкторы не наследуются?
От: dshe  
Дата: 26.07.05 07:03
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, AndrewVK, Вы писали:


SC>>>В чём глубокий смысл сабжа в C#?


AVK>>Одна из причин — необходимость убирать базовые конструкторы.


VD>Лучше бы решили проблему скрытия методов в наследнике.


А зачем может понадобиться скрывать методы в наследнике? Если наследник не реализует весь тот интерфейс, который он унаследовал, то он может и не должен быть наследником? поскольку в этом случае явно нарушается LSP.

Кстати, в С++ по-моему можно в наследнике делать методы приватными, которые в базовом были public.
struct A {
    virtual void f() {}
};

class B: public A {
    virtual void f() {}
};

Что приводит к следующему парадоксу, на мой взгляд.
B *b = new B();
b->f(); // так нельзя -- ошибка компиляции
((A *) b)->f(); // а так уже можно

Получается, что вполне легальными средствами можно доступиться к скрытому методу.
--
Дмитро
Re[8]: Почему конструкторы не наследуются?
От: dshe  
Дата: 26.07.05 07:11
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>В общем, это все попытки скрыть явный прощет в дизайне языков.


ок. Укажи все те условия, при которых, как ты считаешь, наследовать конструкторы безопасно.
--
Дмитро
Re[10]: Почему конструкторы не наследуются?
От: Дарней Россия  
Дата: 26.07.05 07:34
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК> Дарней,


ПК>>> Варианты явным образом закрывать конструкторы подходят не вполне, т.к.

ПК>>> при добавлении базовых классов необходимо будет просматривать всех
ПК>>> наследников, что в общем случае сделать нереально.

Д>> Добавлении базовых классов? Это как?


ПК>Оговорился. При добавлении конструкторов в базовых классах.


Д>> И зачем просматривать всех наследников? Ничего не пойму


ПК>Чтобы убедиться, что их инварианты не нарушаются при добавлении нового конструктора в базе.


Не просто нового конструктора в базе. А такого нового конструктора, который требует соблюдения неких инвариантов его вызова во всех наследниках. Это — во первых.
А во вторых — в этом случае достаточно сделать наследника от базового класса, который перекрывает этот конструктор и делает его protected, а для наследников оставляет открытый конструктор с соблюдением инварианта. Все порожденные классы наследуешь уже от него. И всё!
Всех излечит, исцелит
добрый Ctrl+Alt+Delete
Re[11]: Почему конструкторы не наследуются?
От: dshe  
Дата: 26.07.05 07:45
Оценка:
Здравствуйте, Дарней, Вы писали:

ПК>>Чтобы убедиться, что их инварианты не нарушаются при добавлении нового конструктора в базе.


Д>Не просто нового конструктора в базе. А такого нового конструктора, который требует соблюдения неких инвариантов его вызова во всех наследниках. Это — во первых.


Как новый конструктор в базовом классе обеспечит инициализацию всех полей в тех наследниках, которые их, все-таки, несмотря ни на что, добавляют?

Д>А во вторых — в этом случае достаточно сделать наследника от базового класса, который перекрывает этот конструктор и делает его protected, а для наследников оставляет открытый конструктор с соблюдением инварианта. Все порожденные классы наследуешь уже от него. И всё!


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

Кстати, эти манипуляции с промежуточным базовым классом -- разве это не похоже на написание массы ненужного кода?
--
Дмитро
Re[9]: Почему конструкторы не наследуются?
От: Дарней Россия  
Дата: 26.07.05 07:50
Оценка:
Здравствуйте, dshe, Вы писали:

D>ок. Укажи все те условия, при которых, как ты считаешь, наследовать конструкторы безопасно.


Это безопасно всегда, когда наследники не накладывают ограничений на параметры вызова открытых конструкторов базы. Этого достаточно?
Впрочем, в данном случае это тоже безопасно Просто требует дополнительных действий в виде создания дополнительного класса в иерархии.
Всех излечит, исцелит
добрый Ctrl+Alt+Delete
Re[12]: Почему конструкторы не наследуются?
От: Дарней Россия  
Дата: 26.07.05 08:03
Оценка:
Здравствуйте, dshe, Вы писали:

D>Как новый конструктор в базовом классе обеспечит инициализацию всех полей в тех наследниках, которые их, все-таки, несмотря ни на что, добавляют?


Программисты, которые не ищут себе лишних проблем на задницу, делают это вот так:
class MyClass : BaseClass
{
  SomeClass someVar = new SomeClass();
}

Какие проблемы ты здесь видишь?

D>Так может новый конструтор в базовый класс добавлялся не просто так, а для того, чтобы он был унаследован и экземпляры классов-наследников могли создаваться с его помощью...


Мне кажется, ты просто не понял, о чем идет речь.

D>Кстати, эти манипуляции с промежуточным базовым классом -- разве это не похоже на написание массы ненужного кода?


Немного похоже. Разница только в том, что в одном случае мы делаем один вспомогательный класс и наследуемся от него, а вдругом — копипейстим код вызова конструктора в десятки классов-наследников.
Для тебя это не имеет значения?
Всех излечит, исцелит
добрый Ctrl+Alt+Delete
Re[14]: Почему конструкторы не наследуются?
От: Дарней Россия  
Дата: 26.07.05 08:43
Оценка:
Здравствуйте, dshe, Вы писали:

D>Для поля someVar (в данном примере), возможно не существует умолчательного значения, типа new SomeClass(). И во всех конструкторах (своих) оно инициализируется через параметр.


В таком случае, тебе все равно придется создавать конструкторы вручную — неважно, есть наследование конструкторов или нет

D>Предсказать, какие конструкторы будут добавлены в базовый класс, для того, чтобы их скрыть заранее, либо должным образом переопределить -- задача нереальная.


Ну и не нужно ничего предсказывать. Это задача того, кто добавит конструктор в базовый класс.
Вообще говоря, сделать промежуточный класс, который будет гарантировать соблюдение инварианта для своих наследников — это хорошая идея в любом случае.

D>Возможно. Объясни тогда другими словами. Я пытаюсь принять вашу позицию и найти в ней уязвимые места.


А чего тут непонятного? Промежуточный класс гарантирует соблюдение инвариантадля всей подветки своих наследников. Достигается это тем, что конструктор промежуточного класса соблюдает инвариант всегда, а наследники могут вызвать только этот конструктор, но не конструктор базового класса напрямую.
Всех излечит, исцелит
добрый Ctrl+Alt+Delete
Re[15]: Почему конструкторы не наследуются?
От: dshe  
Дата: 26.07.05 09:01
Оценка:
Здравствуйте, Дарней, Вы писали:

Д>Здравствуйте, dshe, Вы писали:


D>>Для поля someVar (в данном примере), возможно не существует умолчательного значения, типа new SomeClass(). И во всех конструкторах (своих) оно инициализируется через параметр.


Д>В таком случае, тебе все равно придется создавать конструкторы вручную — неважно, есть наследование конструкторов или нет


Верно. Только в случае если конструкторы не наследуются по умолчанию, я буду уверен, что никто не просочится без моего ведома.
--
Дмитро
Re[16]: Почему конструкторы не наследуются?
От: Дарней Россия  
Дата: 26.07.05 09:08
Оценка:
Здравствуйте, dshe, Вы писали:

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


А если будут, ты все равно получишь ворнинг, что поле не проинициализировано
Всех излечит, исцелит
добрый Ctrl+Alt+Delete
Re[9]: Почему конструкторы не наследуются?
От: VladD2 Российская Империя www.nemerle.org
Дата: 26.07.05 13:08
Оценка:
Здравствуйте, dshe, Вы писали:

D>Здравствуйте, VladD2, Вы писали:


VD>>В общем, это все попытки скрыть явный прощет в дизайне языков.


D>ок. Укажи все те условия, при которых, как ты считаешь, наследовать конструкторы безопасно.


Может пусть программист сам решает? Вообще странно выглядит забота о программисте. О конструкторах язык заботится, а о методах нет.

Что до безопасности, то отсуствие новых полей не имеющих инициализации по умолчанию более чем позволяет безопасно наследовать конструкторы.
... << RSDN@Home 1.2.0 alpha rev. 591>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Почему конструкторы не наследуются?
От: VladD2 Российская Империя www.nemerle.org
Дата: 26.07.05 13:31
Оценка:
Здравствуйте, dshe, Вы писали:

D>А зачем может понадобиться скрывать методы в наследнике? Если наследник не реализует весь тот интерфейс, который он унаследовал, то он может и не должен быть наследником? поскольку в этом случае явно нарушается LSP.


Да, конечно можно еще много умных слов сказать. Но вот на практике иногда стоишь перед выбором надолбить ли лишние 100 клиобайт кода обертывающие некий класс и транслирующие к нему вызовы, или создать наследника от класса где есть лишние публичные методы. И почему-то без повышения оплаты долбить лишние 100 кил кода не охота.

D>Кстати, в С++ по-моему можно в наследнике делать методы приватными, которые в базовом были public.

D>
D>struct A {
D>    virtual void f() {}
D>};

D>class B: public A {
D>    virtual void f() {}
D>};
D>

D>Что приводит к следующему парадоксу, на мой взгляд.
D>
D>B *b = new B();
b->>f(); // так нельзя -- ошибка компиляции
D>((A *) b)->f(); // а так уже можно
D>


По-моему, так делать (скрывать члены) просто нельзя. Но я могу ошибаться.

D>Получается, что вполне легальными средствами можно доступиться к скрытому методу.


Согласен, что проблема есть. Но это ведь проблемы реализации. В конце концов меня бы даже устроил бы вариант с запретом приведения к классу у которого бы скрыт метод.
... << RSDN@Home 1.2.0 alpha rev. 591>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: Почему конструкторы не наследуются?
От: VladD2 Российская Империя www.nemerle.org
Дата: 26.07.05 13:58
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Возьми для примера тот же случай наследования немодифицируемого Square

ПК>от немодифицируемого Rectangle.
ПК>[c#]
ПК>class Rectangle
ПК>{
ПК> public Rectangle( int width, int height );

ПК> public int width();

ПК> public int height();

ПК> private int width_;

ПК> private int height_;
ПК>};

ПК>class Square : Rectangle

ПК>{
ПК> public Square( int size );
ПК>};
ПК>[/c]
ПК>Хотя случай и близок к паталогическому, тем не менее, явной ошибки не содержит.

Тут как раз где-то рядом обсуждалась бессмысленность наследования квадратов от прямоугольников. Ну, да идею понял. Проблемы действительно могут быть.

Но объявлять костркуторы тоже не дело. Можно было бы хоть как-то облегчить жизнь программисту. Ну, там некий атрибут ввести, мол у этого класс таки можно наследовать конструкторы. Или еще что.
... << RSDN@Home 1.2.0 alpha rev. 591>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[12]: Почему конструкторы не наследуются?
От: dshe  
Дата: 26.07.05 14:24
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, Павел Кузнецов, Вы писали:


VD>Тут как раз где-то рядом обсуждалась бессмысленность наследования квадратов от прямоугольников. Ну, да идею понял. Проблемы действительно могут быть.


VD>Но объявлять костркуторы тоже не дело. Можно было бы хоть как-то облегчить жизнь программисту. Ну, там некий атрибут ввести, мол у этого класс таки можно наследовать конструкторы. Или еще что.


Кстати, прекрасное применение твоему R#'у -- "наследовать" конструкторы если класс объявлен с аттрибутом, скажем, AddConstructorsFromSuperclass. При этом появление "лишних" конструкторов для программиста уже не будет незаметным (раз он собственноручно указывает такой аттрибут).
--
Дмитро
Re[13]: Почему конструкторы не наследуются?
От: VladD2 Российская Империя www.nemerle.org
Дата: 26.07.05 14:36
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Все проще: для предоставления утилит к существующему классу не нужно от него

ПК>наследоваться. Нужно просто предоставить утилиты. В C++ для этого есть "свободные"
ПК>функции. В C# можно сделать класс со статическими методами. И не будет никаких
ПК>проблем со скрытыми конструкторами и т.п.

Как ты достал со своими утилитами... Я же пару постов тому назад описал ситуацию где мне нужно было наследовать констрктор. Ладно... еще раз...

Есть класс являющийся базовым для типизированных коллекций. От него принципиально только наследуют конкретные классы коллекций. Паттерн такой. Каждая коллекция имеет свой тип. Ну, так вот. Класс дженерик и проблем казалось бы нет. Но вот хотелось бы чтобы конкретные коллекции предоставляли разные кострукторы. Ну, там один с capacity, другой с инициализирующими значениями, третий с сочетаниями первых двух и т.п., и т.д. Уж не промню сколько там было кострукторов, но было не мало. Коллекций от этого класса порождалось штук 10. И в каждой пришлось описывать те же самые конструкторы. В итоге куча кода на пустом месте. А до этого я их генерировал и проблем не знал. Вот тебе и "заюзал" передовые технологии (дженерики).
... << RSDN@Home 1.2.0 alpha rev. 591>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[10]: Почему конструкторы не наследуются?
От: VladD2 Российская Империя www.nemerle.org
Дата: 26.07.05 14:36
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Чтобы убедиться, что их инварианты не нарушаются при добавлении нового конструктора в базе.


А добавление методов в базовый класс ничего нарушить не может?
... << RSDN@Home 1.2.0 alpha rev. 591>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[14]: Почему конструкторы не наследуются?
От: Павел Кузнецов  
Дата: 26.07.05 14:40
Оценка:
VladD2,

V> Есть класс являющийся базовым для типизированных коллекций. От него

V> принципиально только наследуют конкретные классы коллекций. Паттерн
V> такой. Каждая коллекция имеет свой тип. Ну, так вот. Класс дженерик и

Не понял... GenericCollection<int> -- это ж тоже отдельный тип. Зачем от
нее наследовать IntCollection? В чем заключается паттерн? Т.е. какую проблему
он решает, и каким именно образом?
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[11]: Почему конструкторы не наследуются?
От: Павел Кузнецов  
Дата: 26.07.05 14:43
Оценка:
VladD2,

ПК>> Чтобы убедиться, что их инварианты не нарушаются при добавлении нового конструктора в базе.


V> А добавление методов в базовый класс ничего нарушить не может?


Виртуальных в C++ из-за отсутствия декларатора new -- может. В итоге добавлять виртуальные функции
нужно очень осторожно. Но это немного другой случай: виртуальную функцию добавляют именно для того,
чтобы она появилась в наследниках. Конструкторы, все-таки, на неком особом положении по сравнению
с остальными функциями: они устанавливают инварианты класса, создавая класс из "сырой" памяти.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[14]: Почему конструкторы не наследуются?
От: dshe  
Дата: 26.07.05 14:50
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, Павел Кузнецов, Вы писали:


ПК>>Все проще: для предоставления утилит к существующему классу не нужно от него

ПК>>наследоваться. Нужно просто предоставить утилиты. В C++ для этого есть "свободные"
ПК>>функции. В C# можно сделать класс со статическими методами. И не будет никаких
ПК>>проблем со скрытыми конструкторами и т.п.

VD>Как ты достал со своими утилитами... Я же пару постов тому назад описал ситуацию где мне нужно было наследовать констрктор. Ладно... еще раз...


VD>Есть класс являющийся базовым для типизированных коллекций. От него принципиально только наследуют конкретные классы коллекций. Паттерн такой. Каждая коллекция имеет свой тип. Ну, так вот. Класс дженерик и проблем казалось бы нет. Но вот хотелось бы чтобы конкретные коллекции предоставляли разные кострукторы. Ну, там один с capacity, другой с инициализирующими значениями, третий с сочетаниями первых двух и т.п., и т.д. Уж не промню сколько там было кострукторов, но было не мало. Коллекций от этого класса порождалось штук 10. И в каждой пришлось описывать те же самые конструкторы. В итоге куча кода на пустом месте. А до этого я их генерировал и проблем не знал. Вот тебе и "заюзал" передовые технологии (дженерики).


Думаю, что немного кода прояснило бы ситуацию, поскольку я тоже не сразу понял, чем тебе утилиты не подошли. Итак, ты делал приблизительно так:
class Collection<T> {
    // a lot of constructors
}

class CollectionOfInt: Collection<int> {}
class CollectionOfLong: Collection<long> {}
class CollectionOfDouble: Collection<double> {}
// . . .


т.е. ты при помощи наследования решал проблему, которая на C++ решается при помощи typedef'ов?
template<class T>
class Collection {
    // a lot of constructors
};

typedef Collection<int> CollectionOfInt;
typedef Collection<long> CollectionOfLong;
typedef Collection<double> CollectionOfDouble;
// . . .
--
Дмитро
Re[15]: Почему конструкторы не наследуются?
От: VladD2 Российская Империя www.nemerle.org
Дата: 26.07.05 15:10
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Не понял... GenericCollection<int> -- это ж тоже отдельный тип. Зачем от

ПК>нее наследовать IntCollection? В чем заключается паттерн? Т.е. какую проблему
ПК>он решает, и каким именно образом?

Коллекции int-ов конечно никто не создает. Но вот обычные коллекции очень даже. Понимаш ли принято, что коллекции в контролах (и не только) имеют осмысленные имена да и вообще отличаются друг от друга даже если храят одинаковые элементы. Раньше для создания типизированной коллекции нужно было унаследоваться от CollectionBase и реализовать кучу методов. Теперь повилась возможность создать наследника System.Collections.ObjectModel.Collection<T> или своего класса. Все зашибись, но вот конструкторы приходится переопределяь. И если у Collection<T> их всего два, то в моем варианте их было много.
... << RSDN@Home 1.2.0 alpha rev. 591>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[15]: Почему конструкторы не наследуются?
От: VladD2 Российская Империя www.nemerle.org
Дата: 26.07.05 15:10
Оценка:
Здравствуйте, dshe, Вы писали:

D>Думаю, что немного кода прояснило бы ситуацию, поскольку я тоже не сразу понял, чем тебе утилиты не подошли. Итак, ты делал приблизительно так:

D>
D>class Collection<T> {
D>    // a lot of constructors
D>}

D>class CollectionOfInt: Collection<int> {}
D>class CollectionOfLong: Collection<long> {}
D>class CollectionOfDouble: Collection<double> {}
D>// . . .
D>


D>т.е. ты при помощи наследования решал проблему, которая на C++ решается при помощи typedef'ов?

D>
D>template<class T>
D>class Collection {
D>    // a lot of constructors
D>};

D>typedef Collection<int> CollectionOfInt;
D>typedef Collection<long> CollectionOfLong;
D>typedef Collection<double> CollectionOfDouble;
D>// . . .
D>


Ага. Только на С++ проблема typedef-ами не решается. typedef не создает новый тип. Он только лишь дает алиас старому. При этом все типы у тебя будут равны. А требуется именно введение нового типа. Ну, и у конкретных типов коллекций могут переопределяться некоторые вируальные методы.
... << RSDN@Home 1.2.0 alpha rev. 591>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[16]: Почему конструкторы не наследуются?
От: Павел Кузнецов  
Дата: 26.07.05 15:16
Оценка:
VladD2,

ПК>> Не понял... GenericCollection<int> -- это ж тоже отдельный тип.

ПК>> Зачем от нее наследовать IntCollection? В чем заключается
ПК>> паттерн? Т.е. какую проблему он решает, и каким именно образом?

V> Коллекции int-ов конечно никто не создает. Но вот обычные коллекции

V> очень даже. Понимаш ли принято, что коллекции в контролах (и не только)
V> имеют осмысленные имена да и вообще отличаются друг от друга даже если
V> храят одинаковые элементы.

Снова не понял... Какую проблему это решает? Как написал dshe, проблему отсутствия
typedef? Так может, за введение typedef и ратовать? Просто никак не вижу, причем
тут наследование: ведь наследники ничего к поведению базового класса
не добавляют...
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[16]: Почему конструкторы не наследуются?
От: Павел Кузнецов  
Дата: 26.07.05 15:24
Оценка:
VladD2,

V> Ага. Только на С++ проблема typedef-ами не решается. typedef не создает

V> новый тип. Он только лишь дает алиас старому. При этом все типы у тебя
V> будут равны. А требуется именно введение нового типа.

Да, это известный глюк. Но если говорить об изменении языка, то введение strong typedef
могло бы решить проблему.

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1706.pdf

V> Ну, и у конкретных типов коллекций могут переопределяться некоторые вируальные методы.


Вообще-то, в данном случае мне кажтся, что наследникам не понадобятся все конструкторы
базовых классов, т.к. область использования наследников очень ограничена: создали в конструкторе
содержащего класса -- и все дела. На универсальность такая обертка по определению не претендует.
Так что, имхо, и проблемы в данном случае нет...
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[17]: Почему конструкторы не наследуются?
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.07.05 03:40
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:


ПК>Снова не понял... Какую проблему это решает? Как написал dshe, проблему отсутствия typedef? Так может, за введение typedef и ратовать? Просто никак не вижу, причем тут наследование: ведь наследники ничего к поведению базового класса не добавляют...


Re[15]: Почему конструкторы не наследуются?
Автор: VladD2
Дата: 26.07.05

Ага. Только на С++ проблема typedef-ами не решается. typedef не создает новый тип. Он только лишь дает алиас старому. При этом все типы у тебя будут равны. А требуется именно введение нового типа. Ну, и у конкретных типов коллекций могут переопределяться некоторые вируальные методы.


В приципе наличие оператора вроде Type вводящего новый тип было бы очень желательно. Но в данной ситуации это помогло бы не всегда. Иногда нужно переопределять вируатльные методы.
... << RSDN@Home 1.2.0 alpha rev. 591>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[17]: Почему конструкторы не наследуются?
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.07.05 03:40
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Да, это известный глюк. Но если говорить об изменении языка, то введение strong typedef

ПК>могло бы решить проблему.

ПК>http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1706.pdf


Могло бы... это здорово. Но не в плюсах, ни в Шарпе этого нет.

V>> Ну, и у конкретных типов коллекций могут переопределяться некоторые вируальные методы.


ПК>Вообще-то, в данном случае мне кажтся, что наследникам не понадобятся все конструкторы

ПК>базовых классов, т.к. область использования наследников очень ограничена: создали в конструкторе содержащего класса -- и все дела. На универсальность такая обертка по определению не претендует.
ПК>Так что, имхо, и проблемы в данном случае нет...

Это все "твое имхо", а по жизни коллекции создаются и используются в разных местах по разному. И полноценный набор конструкторов не помешал бы. Описывать же их врнучную для каждого типа коллекций откровено в лом. Вот и плюют на них все.
... << RSDN@Home 1.2.0 alpha rev. 591>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[18]: Почему конструкторы не наследуются?
От: Павел Кузнецов  
Дата: 27.07.05 04:18
Оценка:
VladD2,

V> требуется именно введение нового типа. Ну, и у конкретных типов

V> коллекций могут переопределяться некоторые вируальные методы.

Ну, если уже виртуальные методы переопределяются, то не факт, что конструкторы
от базового класса подойдут... Можно пример?
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[18]: Почему конструкторы не наследуются?
От: Павел Кузнецов  
Дата: 27.07.05 04:33
Оценка:
VladD2,

V> Могло бы... это здорово. Но не в плюсах, ни в Шарпе этого нет.


В плюсах более-менее неплохо имитируется в степени, достаточной для практических
целей, с помощью шаблонов конструкторов:
template< class T, class Tag >
struct strong_typedef : T
{
  strong_typedef( T const& t ) : T(t) { }

  template< class A1 >
  strong_typedef( A1& a1 ) : T(a1) { }

  template< class A1, class A2 >
  strong_typedef( A1& a1, A2& a2 ) : T(a1, a2) { }

  template< class A1, class A2, class A3 >
  strong_typedef( A1& a1, A2& a2, A3& a3 ) : T(a1, a2, a3) { }

  // . . .
};

Использование:
struct my_unique_collection_tag;
typedef strong_typedef< Collection<int>, my_unique_collection_tag > MyUniqueCollection;


Хотя тоже, безусловно, не без недостатков:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[11]: Почему конструкторы не наследуются?
От: Павел Кузнецов  
Дата: 27.07.05 06:26
Оценка:
Дарней,

Д>>> И зачем просматривать всех наследников? Ничего не пойму


ПК>> Чтобы убедиться, что их инварианты не нарушаются при добавлении нового

ПК>> конструктора в базе.

Д> Не просто нового конструктора в базе. А такого нового конструктора,

Д> который требует соблюдения неких инвариантов его вызова во всех
Д> наследниках.

Для того, чтобы убедиться, что новый конструктор не нарушит инварианты существующих
наследников, всех наследников нужно будет проанализировать.

Д> Это — во первых. А во вторых — в этом случае достаточно сделать наследника

Д> от базового класса, который перекрывает этот конструктор и делает его protected,
Д> а для наследников оставляет открытый конструктор с соблюдением инварианта. Все
Д> порожденные классы наследуешь уже от него. И всё!

Уже поздно. Они все уже унаследованны от самого класса, в который собрались
добавлять новый конструктор. Или же продемонстрируй, пожалуйста, общую практику
добавления подобных промежуточных классов "на всякий случай".
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[7]: Почему конструкторы не наследуются?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 27.07.05 08:40
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Кстати, проблему можно было бы решить так как это сделано в Дельфи. То есть разрешать только повышать уровень видимости. Тогда можно было бы создавать промежуточные классы с, предполжим, protected свойствами и делать их видимыми в наследниках.


Да, так конечно проблем намного меньше. С другой стороны и ситуация такая нужна бывает нечасто (хотя, опять же, вопрос проектирования библиотек).
А вобще, если немножко пофантазировать, то можно отказаться от классического наследования, оставив реализацию интерфейсов (и множественное наследование их между собой) и добавив миксины (как, кстати, правильно по-русски, подмешивания?).
... << RSDN@Home 1.2.0 alpha rev. 596>>
AVK Blog
Re[19]: Почему конструкторы не наследуются?
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.07.05 15:06
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>VladD2,


V>> требуется именно введение нового типа. Ну, и у конкретных типов

V>> коллекций могут переопределяться некоторые вируальные методы.

ПК>Ну, если уже виртуальные методы переопределяются, то не факт, что конструкторы

ПК>от базового класса подойдут... Можно пример?

Скачай R# и в проекте RSharp.Parser.RsModel погляди коллекции из RSharp\RSharp.Parser.RsModel\CodeDom\Collections\Generic\
... << RSDN@Home 1.2.0 alpha rev. 591>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Почему конструкторы не наследуются?
От: Дарней Россия  
Дата: 11.08.05 10:36
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Явная реализация интерфейсов неплохо с этим справляется.


Вот только есть "один маленький нюанс" — она не работает для методов, унаследованных от базового класса.
Всех излечит, исцелит
добрый Ctrl+Alt+Delete
Re[12]: Почему конструкторы не наследуются?
От: Дарней Россия  
Дата: 11.08.05 10:39
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Для того, чтобы убедиться, что новый конструктор не нарушит инварианты существующих

ПК>наследников, всех наследников нужно будет проанализировать.

То же самое можно сказать про добавление в базовый класс новых методов. И что, наследование методов тоже надо запретить?

ПК>Уже поздно. Они все уже унаследованны от самого класса, в который собрались

ПК>добавлять новый конструктор. Или же продемонстрируй, пожалуйста, общую практику
ПК>добавления подобных промежуточных классов "на всякий случай".

А вот если они "уже" унаследованы от базового класса, а соблюдение инвариантов во всех наследниках гарантируется только методом copy-paste, то разработчику этой архитектуры нужно прямо сейчас больно бить по голове.
Да и рефакторинг еще никто не отменял.
Всех излечит, исцелит
добрый Ctrl+Alt+Delete
Re[14]: Почему конструкторы не наследуются?
От: vdimas Россия  
Дата: 11.08.05 18:18
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>P.S.


ПК>> Все проще: для предоставления утилит к существующему классу не нужно от

ПК>> него наследоваться. Нужно просто предоставить утилиты. В C++ для этого
ПК>> есть "свободные" функции. В C# можно сделать класс со статическими
ПК>> методами. И не будет никаких проблем со скрытыми конструкторами и т.п.

ПК>А для тех редких случаев, где, действительно, имеет смысл наследоваться

ПК>не изменяя инварианты, затрагиваемые конструкторами, в C++ обсуждается введение
ПК>явной возможности наследовать конструкторы базового класса:
ПК>http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1583.pdf

синтаксис не тот, хотелось бы так:

struct Base {
    int i;
    Base(int i_) : i(i_) {}
};

struct Derived : Base {
    using Base::Base;
};


аналогично синтаксиса using для других мемберов.
Re[9]: Почему конструкторы не наследуются?
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.08.05 18:27
Оценка:
Здравствуйте, vdimas, Вы писали:

Такое ощущение, что ты мои слова не читашь.

VD>>Ну, и в чем проблема? Если полей нет или все они инициализируются по месту, то что может помешать наследованию конструктора?


V>Если бы конструкторы наследовались, то мы получили бы грабли в виде возможности неккоректного создания Derived.


А если все же полей нет, или все инициализируется по месту?

V> Intellisense дает нам подсказку двух конструкторов, бери на здоровье. Лекарство состояло бы в принудительном переопределении базовых конструкторов как private. Тогда бы нарушалась инкапсуляция базового класса, ибо любые незначительные изменения в нем (скажем — ввод нового конструктора) потребовал бы доработки ВСЕХ наследников. И жили бы мы весело


Да вариантов придумать можно много. Плохо что выбран был самый примитивный.
... << RSDN@Home 1.2.0 alpha rev. 591>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: Почему конструкторы не наследуются?
От: Дарней Россия  
Дата: 12.08.05 08:16
Оценка:
Здравствуйте, vdimas, Вы писали:

V>
V>class DerivedClass : BaseClass {
V>  using base(...);  // сделать доступными ВСЕ базовые конструкторы, не пересекающиеся по сигнатурам с собственными

V>  using base();             // сделать доступными только определенные сигнатуры.
V>  using base(Type1, Type2);
V>}
V>


V>Код автоинициализированных полей компилятор вставляет в начало КАЖОГО конструктора и сейчас, т.е. он и так участвует в догенерировании кода конструкторов. Резюмируя все это — фича конечно неплохая, но только в случае явного управления ею.


Вполне разумная идея.
Всех излечит, исцелит
добрый Ctrl+Alt+Delete
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.