Нежданно негаданно столкнулся с такой проблемой - решил переопределить ShowModal из второй формы и вызывать его уже с нужными параметрами, вот объявы второй формы: Unit2.h Код (Text): class TForm2 : public TForm { __published: // IDE-managed Components TButton *Button1; TButton *Button2; TBevel *Bevel1; TLabel *Label1; TLabeledEdit *LabeledEdit1; void __fastcall Button2Click(TObject *Sender); void __fastcall Button1Click(TObject *Sender); private: // User declarations public: // User declarations __fastcall TForm2(TComponent* Owner); virtual int __fastcall ShowModal(AnsiString ParentName, int ParentID, int Level); }; Unit2.cpp Код (Text): int __fastcall TForm2::ShowModal(AnsiString ParentName, int ParentID, int Level) { //SomeFunc(...) inherited::ShowModal(); } Так вот, проблема появляется тогда когда я хочу вызвать именно ShowModal без параметров - тоесть Код (Text): Form2->ShowModal(); Компилятор сразу же матерится на то, что существующая версия ShowModal переопределяет виртуальную, как поступить в этой ситуации ?
А у Вас сигнатура для переопределяемого метода одинакова в производном и в базовом классе? Исходя из Ваших отрывков кода не ясна иерархия наследования, а именно: inherited::ShowModal(); inherited - что за класс? Базовый для TForm? Или как? TCustomForm - тоже не ясно, где находится данный класс в иерархии наследования. Покажите нам UML Class Diagram (Диаграмму Классов) по которой писалась реализация. Интуиция мне подсказывает, что ошибка допущена на стадии проектирования - ещё до написания кода.
RedLord Он переопределил метод ShowModal() в производном классе с другой сигнатурой ShowModal(AnsiString ParentName, int ParentID, int Level). В качестве результата получил сокрытие имён. Это ошибка проектирования. Использование using и перенаправляющих функций - это не выход. Лучше правильно проектировать с самого начала, чем потом исправлять такие ошибки.
RedLord Есть установленный набор правил, которых придерживаются при разработке ПО. В данном случае нарушено правило 33 Мейерса, которое гласит: "Не скрывайте унаследованные имена". Источник - Scott Meyers, Effective C++ То есть производный класс был изначально спроектирован некорректно, это привело к сокрытию имён из базового класса, о чём и говорит компилятор: hides - перевод: скрывает Вообщем вместо того чтобы переопределить виртуальную функцию базового класса ShowModal() в производном, он скрыл её методом ShowModal(AnsiString,int,int). Взгляните - сигнатуры у функций разные, о чём ещё можно спорить.
Изменить нет возможности - так как хидеры уже скомпилены Borland'om (ныне CodeGear) и сам код в bpl'ках, а дельфийские сорцы этих модулей ну нет никакого желания править, проще конечно по другому функцию обозвать - но есть же и другой способ - ведь это С++ а не С. Какие еще идеи ? Нафань, я честно не знаком, с UML по отношению к C++ Builder, может и есть такая приблуда в дельфе =) ЗЫ - На данный момент ограничился другим именем функции - чуть больше кода конечно - но принцип жмёт )
Попробуйте применить композицию вместо наследования. Сделайте в классе-обёртке два интерфейсных метода: ShowModal(AnsiString ParentName, int ParentID, int Level) ShowModal() и вызывайте из них реальный ShowModal(), который выполняет всю работу. Что Вам мешает применить композицию?
Ну примерно так, посмотрите подойдёт или нет для Вашего случая идиома композиции: Код (Text): class TForm2 { TForm Object; public: int __fastcall ShowModal(AnsiString ParentName, int ParentID, int Level) { //SomeFunc(...) Object.ShowModal(); } int __fastcall ShowModal() { Object.ShowModal(); } };
Майерс: "1)Имена в производных классах скрывают имена из базовых классов. При открытом наследовании это всегда нежелательно. 2)Чтобы сделать скрытые имена видимыми, используйте using-объявления либо перенаправляющие функции." Только в особых случаях using и перенаправляющие функции, когда выхода другого нет.
Nafanya это он тоже писал? P.S. у ТС ситация описанная как раз в этом правиле. и для того, чтобы не нарушать семантику открытого наследования, нужно вывести наверх и перегруженные функции.
А не проще ли отказаться от попытки назвать функцию именно ShowModal, и назвать ее как-нибудь по-другому, более соответственно реальному положению вещей, скажем ShowCustomModal? так будете иметь и то, и другое, по необходимости. Зачем вам надо именно ShowModal ее назвать?
Именно моя проблема и не позволяет написать ни того ни другого Это VCL, базовые классы уже определены и то, что вы написали - работать не то, что будет... На данный момент так и сделал, но так как проэкт не маленький и к сожалению для пары-человек, то так наиболее удобнее - чем передавать в другое окно всё остальное - а окон очень много - хочется создать как можно больше аналогичных функций и придти к полной шаблонности и юзать одно окно для каждого события. Так вот я и решил принципиально выяснить - есть ли такая возможность в С++ )
Wereww, похоже ваша проблема решается так: Unit2.h Код (Text): class TForm2 : public TForm { . . . virtual int __fastcall ShowModal(); virtual int __fastcall ShowModal(AnsiString ParentName, int ParentID, int Level); . . . }; Unit2.cpp Код (Text): . . . //--------------------------------------------------------------------------- __fastcall TForm2::ShowModal() { return TForm::ShowModal(); } //--------------------------------------------------------------------------- __fastcall TForm2::ShowModal(AnsiString ParentName, int ParentID, int Level) { . . . return TForm::ShowModal(); } //--------------------------------------------------------------------------- . . . Так сразу и ворнинг исчезает, и название сохраняется, можно использовать оба варианта, выбирается корректно в зависимости от набора параметров.
Решение верное, так как ничего не остаётся как переопределять всё заново, ну одной строчкой кода больше, спасибо за солюху, а то голова ватная от этого проэкта