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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> наследование операторов инкремента, как быть с типом 
:(
    Опции темы
Jcs
Дата 27.1.2004, 08:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



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

class CBase
{
public:
virtual CBase& operator++(){...}
virtual CBase& operator--(){...}

virtual CBase operator++(int){...}
virtual CBase operator--(int){...}

};
class CDeriv:public CBase
{
public:
CDeriv& operator++(){CBase::operator++();...} // all ok
CDeriv& operator--(){CBase::operator--();...}     // all ok

CDeriv operator++(int){...}           // error
CDeriv operator--(int){...}             // error
};

Компилятор для первых двух говорит, что типы виртуальных функций должны совпадать, для вторых - все нормально. Неужели единственный выход - отказ от виртуальности? Заранее спасибо.
PM   Вверх
Hroft
Дата 27.1.2004, 10:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 310
Регистрация: 20.10.2003
Где: Москва

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



похоже, единственный, я другого не вижу, да и в STL они не виртуальные (файлик iterator без .h, если я все правильно понял).
PM MAIL ICQ   Вверх
RAN
Дата 27.1.2004, 11:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Экс. модератор
Сообщений: 709
Регистрация: 14.3.2003
Где: Щёлково Моск.обл.

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



Нет смысла делать operator'ы виртуальными. Их всё равно придётся перегружать для каждого конкретного типа и будет выбираться тот оператор, который подходит под тип опреранда.
Например, класс B наследуется от A. В классе A есть вирутальный оператор ++. Теперь если вызвать эту операцию для объекта B, то будет использоваться функция для типа B, а у нас определена только для A.

Код

class A
{
   virtual A& operator++ () {....}
...........................
};

class B : public A
{
...............
};

B b;
++b; //требуется функция B& operator++ (); , а мы унааследовали от A только A& operator++ ()


Теперь по поводу ошибок. Я так понял, под отказом от виртуальности ты понимаешь переписывание этих операторов для каждого класса. Это не правильный подход. Использовать функции из первого класса всё-таки можно и нужно.
Тут дело в том, что нельзя вернуть объект одного класса, как объект совсем другого класса, унаследованого от первого. Тут не проходят простые приведения типов. Класс B должен иметь конструктор от класса A для того, чтобы создать новый объект и вернуть его.
Так что добавь
Код

СDeriv( CBase& obj ) : CBase( obj ) {}

и всё заработает.
PM MAIL ICQ   Вверх
Jcs
Дата 27.1.2004, 13:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



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

CDeriv  d_obj;
CBase b_obj;

CBase& d_obj_ref = d_obj;
CBase& b_obj_ref = b_obj;

d_obj_ref++;
b_obj_ref++;

вызывались нужные операторы, каждый для своего класса. Если операторы будут невиртуальными, то придется городить преобразование типа, к тому же не во всех случаях оно будет безопасным.
PM   Вверх
RAN
Дата 27.1.2004, 21:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Экс. модератор
Сообщений: 709
Регистрация: 14.3.2003
Где: Щёлково Моск.обл.

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



Это решается по другому. Тебе надо ввести вирутальную функция для инкремента и перегрузить operator++, который будет вызывать эту функцию.

Код

class A
{
.......................
   virtual A& prefix_inc()
   {
       ........................
       return *this;
   }
   A& operator++() { return prefix_inc(); }
 
   virtual A& postfix_inc()
   {
       ................
       return *this;
   }
   A& operator++(int) { return postfix_inc(); }

};

class B : public A
{
    virtual A& prefix_inc()
    {
       .......................
        return *this;
    }
    B& operator++() { return (B&)prefix_inc(); }
   
    virtual A& postfix_inc()
    {
       ........................
       return *this;
    }
    B& operator++(int) { return (B&)postfix_inc(); }
};


И насчёт конструтора. Очень странно, что возникала ошибка. Этого не может быть. Но при подходе, описанном чуть выше, это уже не важно.
PM MAIL ICQ   Вверх
Jcs
Дата 28.1.2004, 16:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Спасибо за ответ. Я операторы префиксного типа сделал виртуальными, т.к. они возвращают ссыклку и компилятор не ругается, а постфиксная форма легко реализуется через префиксную.
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

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

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

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

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


 




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


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

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