- C/C++ Перегрузка и наследование ??, frenzy, 15:25 , 31-Июл-05 (1)
>Уважаемые коллеги, укажите, пожалуйста, где я тут не прав: > >---tmp02.cpp--- >class base { >public: > virtual int test() { return 0; }; > virtual int test(int a) { test(); return 0; }; >}; > >class child: public base { >public: > int test() { return 1; }; >}; > >int main(int argc, char *argv[]) { > child c1; > c1.test(1); > return 0; >} > >/* gcc-3.4.4 >Компиляция tmp02.cpp (g++) >tmp02.cpp:15: error: no matching function for call to `child::test(int)' >tmp02.cpp:9: note: candidates are: virtual int child::test() >*** Завершено с кодом: 2 *** >*/ >---tmp02.cpp--- > >С C/C++ я только знакомлюсь, до этого писал на Паскале, >и аналогичный код на нем работает: > >---tmp02.pas--- >program tmp02; >{$APPTYPE CONSOLE} >type > TBase = class > function Test(): Integer; overload; virtual; > function Test(a: Integer): Integer; overload; virtual; > end; > TChild = class(TBase) > function Test(): Integer; override; > end; > >function TBase.Test(): Integer; begin > result := 0; >end; >function TBase.Test(a: Integer): Integer; begin > result := Test(); >end; >function TChild.Test(): Integer; begin > result := 1; >end; > >var > C1: TChild; >begin > C1 := TChild.Create(); > C1.Test(1); >end. >---tmp02.pas--- > >Заранее благодарен, всем кто ответит, >С.Г. Виртуальная функция test() в производном классе у тебя переопределена, соответственно она должна вызываться у тебя без аргуметов.
- C/C++ Перегрузка и наследование ??, С.Г., 16:04 , 31-Июл-05 (2)
>>Уважаемые коллеги, укажите, пожалуйста, где я тут не прав: >> >>---tmp02.cpp--- >>class base { >>public: >> virtual int test() { return 0; }; >> virtual int test(int a) { test(); return 0; }; >>}; >> >>class child: public base { >>public: >> int test() { return 1; }; >>}; >> >>int main(int argc, char *argv[]) { >> child c1; >> c1.test(1); >> return 0; >>} >> >>/* gcc-3.4.4 >>Компиляция tmp02.cpp (g++) >>tmp02.cpp:15: error: no matching function for call to `child::test(int)' >>tmp02.cpp:9: note: candidates are: virtual int child::test() >>*** Завершено с кодом: 2 *** >>*/ >>---tmp02.cpp--- > >Виртуальная функция test() в производном классе у тебя переопределена, соответственно она должна >вызываться у тебя без аргуметов. В том-то и дело, что я переопределяю только одну из двух виртуальных функций с одинаковым названием (а именно test()), но с различным числом параметров, что должно трактоваться как две разных функции (если я ничего не путаю). Соотв. я ожидал, что функция test(int a) достанется в наследство от base, в которой вызывается test(), которую я и собирался переопределять в производных классах. Что же получается, что, переопределив одну из функций, я теряю доступ к остальным функциям с таким же именем? В таком случае теряется смысл перегрузки (по крайней мере, при использовании ее в таком виде). Как выход, придется давать функциям разные имена. Или есть другое решение?
С.Г.
- C/C++ Перегрузка и наследование ??, frenzy, 16:34 , 31-Июл-05 (3)
>>>Уважаемые коллеги, укажите, пожалуйста, где я тут не прав: >>> >>>---tmp02.cpp--- >>>class base { >>>public: >>> virtual int test() { return 0; }; >>> virtual int test(int a) { test(); return 0; }; >>>}; >>> >>>class child: public base { >>>public: >>> int test() { return 1; }; >>>}; >>> >>>int main(int argc, char *argv[]) { >>> child c1; >>> c1.test(1); >>> return 0; >>>} >>> >>>/* gcc-3.4.4 >>>Компиляция tmp02.cpp (g++) >>>tmp02.cpp:15: error: no matching function for call to `child::test(int)' >>>tmp02.cpp:9: note: candidates are: virtual int child::test() >>>*** Завершено с кодом: 2 *** >>>*/ >>>---tmp02.cpp--- >> >>Виртуальная функция test() в производном классе у тебя переопределена, соответственно она должна >>вызываться у тебя без аргуметов. > > >В том-то и дело, что я переопределяю только одну из двух виртуальных >функций с одинаковым названием (а именно test()), но с различным числом >параметров, что должно трактоваться как две разных функции (если я ничего >не путаю). Соотв. я ожидал, что функция test(int a) достанется >в наследство от base, в которой вызывается test(), которую я и >собирался переопределять в производных классах. Что же получается, что, переопределив одну >из функций, я теряю доступ к остальным функциям с таким же >именем? В таком случае теряется смысл перегрузки (по крайней мере, при >использовании ее в таком виде). Как выход, придется давать функциям разные >имена. Или есть другое решение? > >С.Г. Если виртуальная функция не переопределяется в производном классе, то испоьзуется функция базового класса.
- C/C++ Перегрузка и наследование ??, С.Г., 17:12 , 31-Июл-05 (4)
>>>Виртуальная функция test() в производном классе у тебя переопределена, >соответственно она должна >>>вызываться у тебя без аргуметов. >> >> >>В том-то и дело, что я переопределяю только одну из двух виртуальных >>функций с одинаковым названием (а именно test()), но с различным числом >>параметров, что должно трактоваться как две разных функции (если я ничего >>не путаю). Соотв. я ожидал, что функция test(int a) достанется >>в наследство от base, в которой вызывается test(), которую я и >>собирался переопределять в производных классах. Что же получается, что, >переопределив одну >>из функций, я теряю доступ к остальным функциям с таким же >>именем? В таком случае теряется смысл перегрузки (по крайней мере, при >>использовании ее в таком виде). Как выход, придется давать функциям разные >>имена. Или есть другое решение? >> >>С.Г. > >Если виртуальная функция не переопределяется в производном классе, то испоьзуется >функция базового класса. >Вот я на это и надеялся. Тогда что от меня требует компилер?? : tmp02.cpp:15: error: no matching function for call to `child::test(int)' tmp02.cpp:9: note: candidates are: virtual int child::test() Т.е. после переопределения в дочернем классе функции test() компилер как бы не замечает, что в базовом классе помимо test() есть еще и test(int a). С.Г.
- C/C++ Перегрузка и наследование ??, frenzy, 17:21 , 31-Июл-05 (5)
>>>>Виртуальная функция test() в производном классе у тебя переопределена, >соответственно она должна >>>>вызываться у тебя без аргуметов. >>> >>> >>>В том-то и дело, что я переопределяю только одну из двух виртуальных >>>функций с одинаковым названием (а именно test()), но с различным числом >>>параметров, что должно трактоваться как две разных функции (если я ничего >>>не путаю). Соотв. я ожидал, что функция test(int a) достанется >>>в наследство от base, в которой вызывается test(), которую я и >>>собирался переопределять в производных классах. Что же получается, что, >переопределив одну >>>из функций, я теряю доступ к остальным функциям с таким же >>>именем? В таком случае теряется смысл перегрузки (по крайней мере, при >>>использовании ее в таком виде). Как выход, придется давать функциям разные >>>имена. Или есть другое решение? >>> >>>С.Г. >> >>Если виртуальная функция не переопределяется в производном классе, то испоьзуется >функция базового класса. >> > >Вот я на это и надеялся. Тогда что от меня требует компилер?? >: > >tmp02.cpp:15: error: no matching function for call to `child::test(int)' >tmp02.cpp:9: note: candidates are: virtual int child::test() > >Т.е. после переопределения в дочернем классе функции test() компилер как бы не >замечает, что в базовом классе помимо test() есть еще и test(int >a). > >С.Г. Вызывать нужно вот так: base *p;child c1; p = &c1;p->test(1);
- C/C++ Перегрузка и наследование ??, elvenic, 17:26 , 31-Июл-05 (7)
>>>Уважаемые коллеги, укажите, пожалуйста, где я тут не прав: >>> >>>---tmp02.cpp--- >>>class base { >>>public: >>> virtual int test() { return 0; }; >>> virtual int test(int a) { test(); return 0; }; >>>}; >>> >>>class child: public base { >>>public: >>> int test() { return 1; }; >>>}; >>> >>>int main(int argc, char *argv[]) { >>> child c1; >>> c1.test(1); >>> return 0; >>>} >>> >>>/* gcc-3.4.4 >>>Компиляция tmp02.cpp (g++) >>>tmp02.cpp:15: error: no matching function for call to `child::test(int)' >>>tmp02.cpp:9: note: candidates are: virtual int child::test() >>>*** Завершено с кодом: 2 *** >>>*/ >>>---tmp02.cpp--- >> >>Виртуальная функция test() в производном классе у тебя переопределена, соответственно она должна >>вызываться у тебя без аргуметов. > > >В том-то и дело, что я переопределяю только одну из двух виртуальных >функций с одинаковым названием (а именно test()), но с различным числом >параметров, что должно трактоваться как две разных функции (если я ничего >не путаю). Соотв. я ожидал, что функция test(int a) достанется >в наследство от base, в которой вызывается test(), которую я и >собирался переопределять в производных классах. Что же получается, что, переопределив одну >из функций, я теряю доступ к остальным функциям с таким же >именем?(sorry for writing in english, have not been using cyrillic keyboard for several years, forgot layout ;) That's exactly what happens. See, for example: http://cpptips.hyperformix.com/cpptips/virt_name_hide As you can see, that was a confusing topic even in 1991 ;) According to the C++ rules, a name defined in the derived class (in your case, child::test), not overrides, but _hides_ the name from the base class - it means that all methods, data members (perhaps even enum members and embedded classes?) with the same name are not visible in the derived class - the method signature - test() or test(int) - is not taken into account here. В таком случае теряется смысл перегрузки (по крайней мере, при >использовании ее в таком виде). Как выход, придется давать функциям разные >имена. Или есть другое решение?
I'm not sure right away, and am too lazy to test, but something like: child c; c.base::test(5); might work - try it? > >С.Г.
- C/C++ Перегрузка и наследование ??, DeadMustdie, 17:28 , 31-Июл-05 (8)
> child c; > c.base::test(5); Не так. Скорее ((Base&)c).test(5); Однако уродливо. Есть более прямой способ, как я и описал выше.
- C/C++ Перегрузка и наследование ??, DeadMustdie, 17:26 , 31-Июл-05 (6)
1. Практически любому C++-программисту полезно почитать материалы из C++ FAQ: http://new-brunswick.net/workshop/c++/faq/index.html. По неведомым для меня причинам очень мало людей, осведомлённых даже просто о существовании освещённых там тонкостей.2. Ваша проблема лечится добавлением в класс child строки using base::test;
- C/C++ Перегрузка и наследование ??, С.Г., 17:40 , 31-Июл-05 (9)
Всем спасибо! Так я и думал, что нужно дописать некоторую строчку (или как-то хитро вызывать метод), чтобы все стало на свои места.Также спасибо за ссылки (перед тем как постить сюда, я попытался найти ответ сам, но, увы...). Еще раз всем спасибо! С.Г. - C/C++ Перегрузка и наследование ??, frenzy, 17:45 , 31-Июл-05 (10)
>1. Практически любому C++-программисту полезно почитать материалы из >C++ FAQ: http://new-brunswick.net/workshop/c++/faq/index.html. >По неведомым для меня причинам очень мало людей, осведомлённых даже >просто о существовании освещённых там тонкостей. > >2. Ваша проблема лечится добавлением в класс child строки > using base::test; Зачем? если можно вызвать виртуальную функцию через указатель? ;-) как это сделать я описал выше. Помоему автору просто нужно купить книжку по С++ и хорошенько ее проштудировать. Удачи!!!
|