Russian Qt Forum
Июнь 15, 2024, 23:15 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: тупой вопрос: наследование с изменением конструктора  (Прочитано 8842 раз)
josef
Гость
« : Июнь 23, 2006, 10:45 »

у абстрактного класса есть нормальный конструктор без аргументов, при наследовании надо добавить аргументы и несколько действий - как это правильно сделать?
Записан
Вудруф
Гость
« Ответ #1 : Июнь 23, 2006, 11:18 »

Так просто бери и добавляй... В чём проблема-то?
Ты перегружаешь виртуальные функции предка и добавляешь новые (любые) функции.
Записан
josef
Гость
« Ответ #2 : Июнь 23, 2006, 11:45 »

Меня, как тщайника, интересует синтаксис =)
Вот есть у меня код:
Код:

class MyAbstractClass
{
  MyAbstractClass()
  {
    i = 0;
  };
  virtual void my_virtual_function....
  int i;
};


если я напишу вот так:
Код:

class MyInheritClass : public MyAbstractClass
{
  MyInheritClass( int _j )
  {
    j = _j;
  };
  void my_virtual_function......
  int j;
}

у меня будет выполняться и i = 0 из родительского конструктора и j = _j из наследника? - как-то странновато выглядит  :shock:

UPD: нашел, что в конструкторе наследника надо вызвать конструктор родителя. Из cерии "и как я сам не допёр!?"  :mrgreen:
Записан
Вудруф
Гость
« Ответ #3 : Июнь 23, 2006, 13:30 »

Во втором классе функция объявлена неправильно. Ты же её перегрузить хочешь? Тогда писать virtual по прежнему надо, просто у первого класса она должна быть чисто виртуальной: virtual void my_virtual_function (...) = 0
Первый конструктор лучше делать так:
MyAbstractClass() : i(0)
{
}
Второй так:
MyInheritClass (int _j) : MyAbstractClass(), j (_j)
{
}
Впрочем, вызывать конструктор предка можно и в теле. А вот переменные лучше делать так, т.к. первоначально для них вызывается конструктор по умолчанию.
Итого, для конструкции
MyInheritClass (int _j)
{
  j = _j;
}
происходит следующее:
j = 0;
j = _j;
Для конструктора
MyInheritClass (int _j) : j(_j)
{
}
только
j = _j;
Т.е. конструкция i = 0 вообще лишняя, но ради наглядности можно добавить i(0), лишних операций происходить не будет.

А вообще, всё гораздо лучше описано у Страуструпа...
Записан
josef
Гость
« Ответ #4 : Июнь 23, 2006, 14:13 »

Цитировать
А вообще, всё гораздо лучше описано у Страуструпа...

Вот где там?? Я не смог найти =\ (Специальное издание - "Бином" Москва, 2005)
Записан
vsb
Гость
« Ответ #5 : Июнь 25, 2006, 23:23 »

Цитировать
нашел, что в конструкторе наследника надо вызвать конструктор родителя. Из cерии "и как я сам не допёр!?"  :mrgreen:

Не надо, конструктор по умолчанию (без параметров) и так вызывается, без его явного указания, явное указание требуется, если нужно передать какие-то параметры конструктору предка.

Цитировать

Во втором классе функция объявлена неправильно. Ты же её перегрузить хочешь? Тогда писать virtual по прежнему надо,

Не надо, достаточно того, чтобы совпадали сигнатуры (т.е. возвращаемые типы и типы аргументов)
Записан
Вудруф
Гость
« Ответ #6 : Июнь 26, 2006, 09:17 »

Первое я знал. Я показал способ вызова конструктора предка из конструктора потомка.
А про второе спасибо. Посмотрел в Страуструпе - действительно так. Учиться никогда не поздно Улыбающийся
Записан
Вудруф
Гость
« Ответ #7 : Июнь 28, 2006, 20:03 »

Забавная выдержка из Mozilla C++ portabilty guide:

Цитировать

Use virtual declaration on all subclass virtual member functions.

Non-portable example:

class A {
  virtual void foobar(char*);
};

class B : public A {
  void foobar(char*);
};

Another drag. In the class declarations above, A::foobar() is declared as virtual. C++ says that all implementations of void foobar(char*) in subclasses will also be virtual (once virtual, always virtual). This code is really fine, but some compilers want the virtual declaration also used on overloaded functions of the virtual in subclasses. If you don't do it, you get warnings. While this is not a hard error, because this stuff tends to be in headers files, you'll get so many warnings that's you'll go nuts. Better to silence the compiler warnings, by including the virtual declaration in the subclasses. It's also better documentation:

Portable example:

class A {
  virtual void foobar(char*);
};

class B : public A {
  virtual void foobar(char*);
};
Записан
Литий
Гость
« Ответ #8 : Август 01, 2006, 13:07 »

Цитата: "Вудруф"
Во втором классе функция объявлена неправильно. Ты же её перегрузить хочешь? Тогда писать virtual по прежнему надо

Да - не надо, но желательно Улыбающийся
Цитата: "Вудруф"
Впрочем, вызывать конструктор предка можно и в теле.

Нет, конструктор явно в С++ не вызвать.
Цитировать

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

Это имеет значение только для сложных типов. Переменные простых типов (типа int) автоматически не инициализируются и должны быть инициализированы в конструкторе! Поэтому для простых типов оба варианта равноправны - вопрос только в стиле.

добавлено спустя 3 минуты:

 
Цитировать

Не надо, достаточно того, чтобы совпадали сигнатуры (т.е. возвращаемые типы и типы аргументов)
В Паскале (Delphi), кстати, виртуальные функции вводятся словом virtual, а переопределяются - словом override. Имхо, удачно.  Улыбающийся
Записан
kolobok0
Гость
« Ответ #9 : Август 01, 2006, 18:44 »

Цитата: "Вудруф"
...Тогда писать virtual по прежнему надо, просто у первого класса она должна быть чисто виртуальной: virtual void my_virtual_function (...) = 0...



1) как уже было сказано выше - чтоб перекрыть не надо писать виртуал...
2) "у первого класса" она МОЖЕТ быть чисто виртаульной, а может и НЕ БЫТЬ... Зависит от реализации. Термин "чисто виртуальный метод" - означает лишь то, что данный класс НЕ СОДЕРЖИТ реализации данного метода. Соотвестственно Вы накладываете (такой реализацией) ограничение на создание экземпляров таких классов. Когда это нуна ?

Пример:
Вы выделили общую сущность у кошки и собаки в виде четырёх лап, головы, туловища, хвоста. Назвали всё эту батву "Остов" и смело отнаследовали от неё отдельно кошку и отдельно собаку. Чтоб в памяти компа не бегали безликие "Остовы" - Вы говорите (например), что метод "Звук" будет чисто виртуальным (ну не знаете Вы - будет гавкать или мяукать!) и определяеться в наследнике. Ту да же (в наследника): пол, форма головы, скорость передвижения, способность лазить по деревьям и т.д. и т.п...


Другими словами, рекомендую почитать что нить по ООА. Например "библию" Гради Буча...


с уважением
(круглый)
Записан
Вудруф
Гость
« Ответ #10 : Август 09, 2006, 17:55 »

=0 я приписал, т.к. название было MyAbstractClass
А про virtual - я уже выше отписался, что накосячил Улыбающийся

добавлено спустя 35 секунд:

 А книги по ООП я читал...
Записан
bigirbis
Гость
« Ответ #11 : Сентябрь 09, 2006, 14:10 »

pure virtual class не обязательно должен содержать только pure virtual методы, для этого достаточно объявить только один такой метод. Остальные методы могут быть значащими. Это зависит от поставленной задачи.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.045 секунд. Запросов: 20.