2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему
 
 Конструкторы и наследование в С++
Сообщение17.09.2013, 19:39 


04/06/13
15
Здравствуйте!
Допустим, есть класс Employee, от него наследуется класс Manager, от него Scientist. Верно ли я понял, что конструкторы каждого
производного класса должны содержать конструкторы базовых классов?
Т.е. в Manager - конструктор от Employee, а в Scientist - Manager, содержащий в себе конструктор от Employee?

Код:
#include <iostream>
////////////////////////////////////////
class Employee
{
protected:
   int empNum;
   char* empSurname;
public:
   Employee(): empNum(-1), empSurname(NULL) {};
   Employee(int num, char* adrS): empNum(num), empSurname(adrS) {};
   ~Employee()
   {
      delete empSurname;
   }
   void displayS(int N);
} ;
void Employee::displayS(int N)
{
   if (N)
   {      
      std::cout << "\nСотрудник №" << empNum << ':'
             << "\nФамилия: " << empSurname;
   }
   else
      std::cout << "\nСписок пуст!";   
}
////////////////////////////////////////
class Manager : public Employee
{
private:
   char* empPosition;
public:
   Manager(): empPosition(NULL) {};
   Manager(int num, char* adrS, char* adrP):
         Employee(num, adrS)
      { empPosition = adrP; }
   ~Manager()
   {
      delete empPosition;
   }
   void displayP();
} ;
void Manager::displayP()
{
   std::cout << "\nДолжность: " << empPosition;
}
////////////////////////////////////////
class Scientist : public Manager
{
private:
   int pubs;
public:
   Scientist(): pubs(-1) {};
   Scientist(int num, char* adrS, char* adrP, int p):
         Manager(num, adrS, adrP)
         { pubs = p; }
   void displayPubs();
} ;
void Scientist::displayPubs()
{
   if (pubs)
      std::cout << "\nКоличество публикаций: " << pubs;
   else
      std::cout << "\nПубликаций нет!";   
}


 Профиль  
                  
 
 Re: Конструкторы и наследование в С++
Сообщение17.09.2013, 19:49 
Заслуженный участник


04/05/09
4589
Конструктор базового класса вызовется в любом случае. От того, написали ли вы вызов, зависит, какой именно конструктор базового класса вызовется. Если вы не написали его явно, то вызовется конструктор по умолчанию (без параметров, или где все параметры имеют значение по умолчанию).

 Профиль  
                  
 
 Re: Конструкторы и наследование в С++
Сообщение17.09.2013, 19:56 


04/06/13
15
venco
Спасибо за ответ ;)

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

 Профиль  
                  
 
 Re: Конструкторы и наследование в С++
Сообщение17.09.2013, 20:35 
Заслуженный участник


04/05/09
4589
Что вы имеете в виду под автономны, и в каком направлении у вас высшие?
Конструкторы производных классов вызывают конструкторы предков (и членов), как функции.

 Профиль  
                  
 
 Re: Конструкторы и наследование в С++
Сообщение17.09.2013, 20:36 
Заслуженный участник


28/04/09
1933
Dexter_Fl в сообщении #764757 писал(а):
Они автономны или нужно учитывать высшие по иерархии?
Что значит "автономны"?

Перед выполнением тела конструктора дочернего класса будут вызваны конструкторы родительских классов в том порядке, в каком эти классы перечислены в списке наследования при объявлении дочернего класса. В списке инициализации конструктора дочернего класса для каждого родительского класса Вы можете указать, какой именно конструктор для него будет вызван. Если не укажете, то вызовется конструктор по умолчанию.
Тут надо заметить, что если Вы не определите в классе ни одного конструктора, то конструктор по умолчанию будет сгенерирован компилятором автоматически. Но если хотя бы один конструктор определен, то конструктор по умолчанию генерироваться не будет, со всеми вытекающими последствиями.
Также надо заметить, что в случае виртуального наследования механизм немного отличается.

 Профиль  
                  
 
 Re: Конструкторы и наследование в С++
Сообщение17.09.2013, 21:02 
Заслуженный участник


09/09/10
3729
Офф-топ, но. У вас char*указатели передаются в конструктор с контрактом "создаваемый объект во время разрушения удалит переданный ему указатель используя delete". Это означает, например, что программа

Код:
    char *frank = "Frank";
    { Employee employee(0, frank); }
вылетит с Access Violation / SEGFAULT.

 Профиль  
                  
 
 Re: Конструкторы и наследование в С++
Сообщение19.09.2013, 10:36 


04/06/13
15
Спасибо всем, кто написал!

Иерархия такова: базовый Employee, от него Manager, от него Scientist

Я имел в виду, что при описании конструктора Manager, нужно вызвать предыдущий конструктор.

Код:
Manager(int num, char* adrS, char* adrP):
         Employee(num, adrS)
      { empPosition = adrP; }


Верно ли я понял, как должны быть построены конструкторы при наследовании?

Joker_vD

Спасибо за помощь ;)
Но я не понял, каким образом можно устранить эту оплошность?

 Профиль  
                  
 
 Re: Конструкторы и наследование в С++
Сообщение19.09.2013, 10:51 
Заслуженный участник
Аватара пользователя


19/12/10
1546
Dexter_Fl в сообщении #765276 писал(а):
Но я не понял, каким образом можно устранить эту оплошность?

Удалите деструкторы.
Для Ваших классов вполне достаточно автоматически генерируемых компилятором.
Объекты будут корректно удаляться при выходе из области видимости.
А память возвращайте в кучу в той области видимости где её брали оператором new (операторы new и delete подобны открывающей и закрывающей скобке соответственно).

 Профиль  
                  
 
 Re: Конструкторы и наследование в С++
Сообщение19.09.2013, 11:00 


10/04/12
705
Dexter_Fl в сообщении #765276 писал(а):

Joker_vD

Спасибо за помощь ;)
Но я не понял, каким образом можно устранить эту оплошность?


Самое простое для С++---использовать std::string и не париться. Или принимать const char *, вычислять его длину, выделать место в куче под него, копировать и забыть.

 Профиль  
                  
 
 Re: Конструкторы и наследование в С++
Сообщение19.09.2013, 11:22 


04/06/13
15
mustitz

Да, согласен по поводу string. Но, увы, условия задачи - использовать в классе const char *.

Код:
Parent(const char* tempS)
      : surname(new char[strlen(tempS) + 1])
   {
      strcpy(surname, tempS);
   }

Вы имеете в виду эту реализацию?

-- 19.09.2013, 12:28 --

whitefox

Хм. Вот, например, здесь:
Код:
Child(const char* tempS, const char* tempN) :
      Parent(tempS)
   {
      name = new char[strlen(tempN) + 1];
      strcpy(name, tempN);
   }


Я выделил память для const char* переменной класса Child. Занес в нее данные. И тут же удаляю выделенную память?

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 10 ] 

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group