| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > переопределение оператора |
| Автор: VictorOff 4.10.2011, 10:38 |
| Уважаемые форумчане, подскажите пожалуйста, можно ли решить следующую проблему: Имеется интерфейс класса IBase и класс реализации TBase, в нем переопределен оператор (). class IBase { public: virtual int operator()(int Value)=0; }; //--------------------------------------------------------------------------- class TBase : public IBase { public: virtual int operator()(int Value) {return Value*2;} }; Чтобы воспользоваться прелестями работы с переопределенным оператором необходимо использовать крайне несимпатичный синтаксис разыменования IBase *Base=new TBase(); int iResult=(*Base)(2); Нельзя ли этого избежать, скажем как-нибудь через интеллектуальный указатель? |
| Автор: newbee 4.10.2011, 10:43 |
| Напиши такой интеллектуальный указатель, у которого оператор () будет вызывать оператор () своего указателя. Еще можешь вызывать так: object->operator()(1,2,3), а еще лучше не заниматься такой ерундой и дать вменяемое имя методу. |
| Автор: Earnest 4.10.2011, 10:49 |
| Можно, если напишешь соответствующую обертку. Причем виртуальный это оператор или нет - по барабану. Но придется всегда либо использовать эту обертку вместо указателя на интерфейс, либо каждый раз оборачивать указатель при вызове (), что еще менее симпатично. Еще можно макрос нарисовать. Да и сама идея включения виртуальных операторов в интерфейс кажется мне некошерной. Оператор () у объекта - это обобщение функции; обычно принимается, что такие объекты (функторы) очень маленькие, легкие и имеют малую стоимость... и практически не имеют прочего интерфейса. |
| Автор: VictorOff 4.10.2011, 12:33 |
Спасибо всем, кто откликнулся, согласен, приведенный пример переопределения весьма скользкий, но если рассмотрим переопределение оператора преобразования class IBase { public: virtual operator int()=0; }; //--------------------------------------------------------------------------- class TBase : public IBase { public: virtual operator int() { return 293; } }; //--------------------------------------------------------------------------- то по моему достаточно удобно было бы использовать в виде IBase *Base=new TBase(); int n=Base*7; я пробовал представить как это будет выглядеть с использованием интеллектуального указателя template <class Type > class TSP { private: Type* pointer; public: TSP() : pointer(new Type()) {} TSP(Type* p) : pointer(p) {} ~TSP() { delete pointer; } operator Type*() { return pointer; } Type* operator->() { return pointer; } operator int() {return static_cast<int> (*pointer); } }; TSP<TBase> sp; int n=sp*7; но тогда из-за включения строчки «operator int() {return static_cast<int> (*pointer); }» этот ИУ будет не универсальным, а заточенным под конкретный класс. Тогда к каждому классу надо делать персональный ИУ? |
| Автор: Earnest 4.10.2011, 13:19 |
Операторы приведения еще более некошерно использовать в интерфейсах. Да еще и делать виртуальными - вообще жуть. Операторы приведения - вообще штука опасная, и должны использоваться с большим разбором... Сделай, как тебе уже советовали, метод с вменяемым именем. Ей-богу, кучи проблем избежишь. Я уж не говорю об удобстве последующего рефакторинга... |
| Автор: VictorOff 4.10.2011, 13:28 |
| Всем спасибо, убедили. |
| Автор: math64 4.10.2011, 18:26 | ||
Кстати, инеллектуальный указатель для этого случая разрабатывать не нужно, он уже встроен в язык, называется ссылка
Но все же вместо оператора лучше использовать обычную функцию |
| Автор: mes 4.10.2011, 23:58 | ||
само переопределение оператора тут не причем.. |