Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> переопределение оператора, возможно ли без разыменования указателя 
:(
    Опции темы
VictorOff
Дата 4.10.2011, 10:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 22
Регистрация: 6.8.2007

Репутация: нет
Всего: нет



Уважаемые форумчане, подскажите пожалуйста, можно ли решить следующую проблему:
Имеется интерфейс класса 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);  
Нельзя ли этого избежать, скажем как-нибудь через интеллектуальный указатель? 

PM MAIL   Вверх
newbee
Дата 4.10.2011, 10:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бревно
**


Профиль
Группа: Участник
Сообщений: 703
Регистрация: 24.8.2011

Репутация: 4
Всего: 19



Напиши такой интеллектуальный указатель, у которого оператор () будет вызывать оператор () своего указателя. Еще можешь вызывать так: object->operator()(1,2,3), а еще лучше не заниматься такой ерундой и дать вменяемое имя методу.


--------------------
You're face to face
With man who sold the world
PM   Вверх
Earnest
Дата 4.10.2011, 10:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Можно, если напишешь соответствующую обертку. Причем виртуальный это оператор или нет - по барабану.
Но придется всегда либо использовать эту обертку вместо указателя на интерфейс, либо каждый раз оборачивать указатель при вызове (), что еще менее симпатично. Еще можно макрос нарисовать.
Да и сама идея включения виртуальных операторов в интерфейс кажется мне некошерной. Оператор () у объекта - это обобщение функции; обычно принимается, что такие объекты (функторы) очень маленькие, легкие и имеют малую стоимость... и практически не имеют прочего интерфейса.


--------------------
...
PM   Вверх
VictorOff
Дата 4.10.2011, 12:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 22
Регистрация: 6.8.2007

Репутация: нет
Всего: нет




Спасибо всем, кто откликнулся, согласен, приведенный пример переопределения весьма скользкий, но если рассмотрим переопределение оператора преобразования

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); }» этот ИУ будет не универсальным, а заточенным под конкретный класс. Тогда к каждому классу надо делать персональный ИУ?

PM MAIL   Вверх
newbee
Дата 4.10.2011, 13:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бревно
**


Профиль
Группа: Участник
Сообщений: 703
Регистрация: 24.8.2011

Репутация: 4
Всего: 19



Цитата(VictorOff @  4.10.2011,  13:33 Найти цитируемый пост)
IBase *Base=new TBase();
int n=Base*7;
Неудобно. А если там будет base+42, как это понимать? Как смещение по буферу или как преобразование и сложение? А (char*)buf+42 тоже должен складывать численное представление первой буквы строки с 42?

Цитата(VictorOff @  4.10.2011,  13:33 Найти цитируемый пост)
но тогда из-за включения строчки «operator int() {return static_cast<int> (*pointer); }» этот ИУ будет не универсальным, а заточенным под конкретный класс. Тогда к каждому классу надо делать персональный ИУ?
Можно сделать универсальный базовый класс-указатель и генерировать (макросами, шаблонами или вообще внешними средствами) дочерние, под определенный тип с определенными операторами. Но техническая возможнось решения задачи еще не делает эту задачу  нужной smile

Это сообщение отредактировал(а) newbee - 4.10.2011, 13:12


--------------------
You're face to face
With man who sold the world
PM   Вверх
Earnest
Дата 4.10.2011, 13:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Цитата(VictorOff @  4.10.2011,  13:33 Найти цитируемый пост)
но если рассмотрим переопределение оператора преобразования

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


--------------------
...
PM   Вверх
VictorOff
Дата 4.10.2011, 13:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 22
Регистрация: 6.8.2007

Репутация: нет
Всего: нет



Всем спасибо, убедили.
PM MAIL   Вверх
math64
Дата 4.10.2011, 18:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



Кстати, инеллектуальный указатель для этого случая разрабатывать не нужно, он уже встроен в язык, называется ссылка
Код

void test() {
IBase& RBase = *new TBase();
int n1 = RBase(2);
int n2 = (int)RBase+42;
delete &RBase;
}

Но все же вместо оператора лучше использовать обычную функцию
PM   Вверх
mes
Дата 4.10.2011, 23:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(VictorOff @  4.10.2011,  09:38 Найти цитируемый пост)
переопределение оператора, возможно ли без разыменования указателя

 smile 
само переопределение оператора тут не причем..



--------------------
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0513 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.