1

Тема: Динамічна типізація в C++

Задача - розробити програму "Відділ кадрів". Але в постановці задачі, є деякі речі, які мене бентежать.

Логічна структура даних
1. Інформаційний об’єкт "робітник". Помимо звичайних атрибутів є такий: Назва - "Підрозділ, де працює", а тип - Об’єкт типу "підрозділ".

2. Інформаційний об’єкт "підрозділ". Аналогічно, є певні атрибути і ось такий: Назва - Робітники підрозділу, а тип -
Структура даних з об’єктів типу "робітник".

От як це? Якщо ще на python можна зробити щось отаке:

Прихований текст
class Department(object):
    def __init__(self, name):
        self.name = name
        self.workers = []
 
    def get_name(self):
        return self.name
 
    def add_worker(self, worker):
        self.workers.append(worker)
 
    def get_workers(self):
        return self.workers
 
 
class Worker(object):
    def __init__(self, name, department):
        self.name = name
        self.department = department
        self.department.add_worker(self)
 
    def get_name(self):
        return self.name
 
    def get_department_name(self):
        return self.department.get_name()
 
managers = Department('manager')
major_manager = Worker('John', managers)
print major_manager.get_department_name()

то на С++ неможливо, бо масив (тут - self.workers = []) повинен бути якогось типу, чи навіть якщо вказівники, то вони якогось типу. А в Department ми не можемо використовувати тип Worker, бо він ще не оголошений. То як же вийти із цієї ситуації? Чи може завдання некоректно поставлене? Бо навіть з Python воно якось негарно виглядить як на мене.

Подякували: div3la1

2

Re: Динамічна типізація в C++

Динамічна типізація, це як контрацепція на 3 місяці вагітності.

3

Re: Динамічна типізація в C++

А в Department ми не можемо використовувати тип Worker, бо він ще не оголошений.

Можна попередньо оголосити клас, який буде описано згодом:

class Worker; //оголошення без опису

class Department
    {
    //десь тут використовуємо посилання на Worker
    };

class Worker
   {
   //опис класу
   }
Подякували: koala, leofun01, pika19893

4

Re: Динамічна типізація в C++

Правильна відповідь вже є; можу ще додати, що можна зробити підрозділ і працівника нащадками одного класу (Object, скажімо) і додати масиви посилань на Object-и. Але це неправильний спосіб.

5 Востаннє редагувалося algoman (02.03.2016 00:29:34)

Re: Динамічна типізація в C++

pika1989 написав:

Задача - розробити програму "Відділ кадрів". Але в постановці задачі, є деякі речі, які мене бентежать.

Логічна структура даних
1. Інформаційний об’єкт "робітник". Помимо звичайних атрибутів є такий: Назва - "Підрозділ, де працює", а тип - Об’єкт типу "підрозділ".

2. Інформаційний об’єкт "підрозділ". Аналогічно, є певні атрибути і ось такий: Назва - Робітники підрозділу, а тип -
Структура даних з об’єктів типу "робітник".

От як це? Якщо ще на python можна зробити щось отаке:

Прихований текст
class Department(object):
    def __init__(self, name):
        self.name = name
        self.workers = []
 
    def get_name(self):
        return self.name
 
    def add_worker(self, worker):
        self.workers.append(worker)
 
    def get_workers(self):
        return self.workers
 
 
class Worker(object):
    def __init__(self, name, department):
        self.name = name
        self.department = department
        self.department.add_worker(self)
 
    def get_name(self):
        return self.name
 
    def get_department_name(self):
        return self.department.get_name()
 
managers = Department('manager')
major_manager = Worker('John', managers)
print major_manager.get_department_name()

то на С++ неможливо, бо масив (тут - self.workers = []) повинен бути якогось типу, чи навіть якщо вказівники, то вони якогось типу. А в Department ми не можемо використовувати тип Worker, бо він ще не оголошений. То як же вийти із цієї ситуації? Чи може завдання некоректно поставлене? Бо навіть з Python воно якось негарно виглядить як на мене.

Підтримую, те що ви зробили на Python і те що вам порадили негарно виглядить. Негарно виглядить!

6

Re: Динамічна типізація в C++

P.Y. написав:

А в Department ми не можемо використовувати тип Worker, бо він ще не оголошений.

Можна попередньо оголосити клас, який буде описано згодом:

class Worker; //оголошення без опису

class Department
    {
    //десь тут використовуємо посилання на Worker
    };

class Worker
   {
   //опис класу
   }

Не працює, на жаль.
Зробила ось так:

Прихований текст
class Department;

class Worker: public Person
{
    int account_number_salary;
    Department department;
    Position position;
    Project projects[NUMBER_LAST_PROJECTS];
    int current_number_projects;
    double experience;
    double total_projects_cost;
};

class Department
{
    string name;
    Worker *workers;
    int number_workers;
    string major_department_name;
    double amount_prize;
    string *positions;
    int number_positions;
};

Видає помилку:  'Worker::department' uses undefined class 'Department'.

Чи може я щось не так зробила?

7

Re: Динамічна типізація в C++

Читаємо уважно:

pika1989 написав:
P.Y. написав:
//десь тут використовуємо посилання на Worker

Уважніше:

pika1989 написав:
P.Y. написав:
//посилання на Worker

Ще уважніше:

pika1989 написав:
P.Y. написав:
//посилання

А у вас department як проголошений?

Подякували: pika1989, leofun012

8 Востаннє редагувалося pika1989 (12.03.2016 10:53:24)

Re: Динамічна типізація в C++

Зробила ось так:

class Worker;

class Department
{
    string name;
    Worker *&workers;
    int number_workers;
    string major_department_name;
    double amount_prize;
    string *positions;
    int number_positions;
};
class Worker : public Person
{
    int account_number_salary;
    Department department;
    Position position;
    Project projects[NUMBER_LAST_PROJECTS];
    int current_number_projects;
    double experience;
    double total_projects_cost;
};

Але тоді виникають запитання:
1. Як працювати з масивом працівників, якщо його фактично ще не існує?
2. Як його ініціалізувати у конструкторі по-замовчуванню? Чи цього робити взагалі не потрібно?
У класі Department конструктор має вигляд:

Department()
    {
        name = "no name department";
        workers = NULL;
        number_workers = 0;
        major_department_name = "no name";
        amount_prize = 0;
        positions = NULL;
        number_positions = 0;
    }


І видає помилку: "Department::Department()" provides no initializer for: reference member Department::workers"    .
Поясніть, будь ласка, як тут бути.

9

Re: Динамічна типізація в C++

Давайте припинимо гратися зі значками і розберемося в тому, що вам дійсно потрібно.
У вас є підрозділи і працівники. Давайте спробуємо відповісти на питання:
- чи може існувати працівник без підрозділу?
- чи може існувати підрозділ без працівників?
- чи може бути в одному підрозділі багато працівників?
- чи може бути один працівник в багатьох підрозділах?
- що стається з підрозділом, коли останній працівник звільняється з нього?
- що стається з працівником, коли єдиний підрозділ, де він працював, ліквідовується?
- (складне питання, бажано скласти табличку - хоча б подумки) який об'єкт(и) відповідає за зберігання якої саме інформації? Якщо за одну інформацію відповідає одразу два об'єкти, то як гарантується, що інформація буде несуперечливою?

А у вас тут в кожного працівника є об'єкт department - тобто скільки працівників, стільки й підрозділів, виходить?

10

Re: Динамічна типізація в C++

Я розумію, як воно виглядає, але є завдання (у файлі), яке мушу дотримати і виконати *PARDON*

Post's attachments

HRS_5.doc 61.5 kb, 404 downloads since 2016-03-12 

11

Re: Динамічна типізація в C++

Прихований текст

оце було б круто, якби у кожного викладача був би документ, котрий засвідчував його лвл. Типу, викладач 80 лвла, і щоб викладач з вищим лвлом міг відміняти або змінювати завдання дані викладачем нижчого лвла.

12

Re: Динамічна типізація в C++

Чудове завдання - по рядку коду на рядок завдання, якби мова була SQL :)
Тоді просто запам'ятайте, що з точки зору завдання немає різниці - об'єкт включений до іншого (композиція), доданий окремо (агрегація) чи просто пов'язаний (посилання). Це питання програміста - який тип зв'язку встановити в якому місці. Тобто якщо сказано "в об'єкта X має бути властивість Y", то це не обов'язково означає

class X{
  Y y;
  public: Y* getY(){
    return &y;
  }
};

це може означати

class X{
  Y *y;
  public: Y* getY(){
    return y;
  }
};

і навіть

class Y{
  X *x;
};
class X{
  Y* getY(){
    for(&y: list_of_all_Ys){
      if(y.x==this){
        return &y;
      }
  }
};

Головне - що можна запитати в об'єкта і отримати відповідь.

Подякували: leofun011

13

Re: Динамічна типізація в C++

FakiNyan написав:
Прихований текст

оце було б круто, якби у кожного викладача був би документ, котрий засвідчував його лвл. Типу, викладач 80 лвла, і щоб викладач з вищим лвлом міг відміняти або змінювати завдання дані викладачем нижчого лвла.

Це зветься "посада", декан може скасувати рішення викладача :)

14

Re: Динамічна типізація в C++

koala, я Вам дякую за пояснення, але мені не зовсім зрозуміло як бути в моєму випадку...
Тобто, можна зробити щоб у класі Підрозділ був масив об'єктів Працівник, а у класі Працівник достатньо лише назву підрозділу типу string?

15

Re: Динамічна типізація в C++

koala написав:
FakiNyan написав:
Прихований текст

оце було б круто, якби у кожного викладача був би документ, котрий засвідчував його лвл. Типу, викладач 80 лвла, і щоб викладач з вищим лвлом міг відміняти або змінювати завдання дані викладачем нижчого лвла.

Це зветься "посада", декан може скасувати рішення викладача :)

декан не може розбиратись у всьому краще за всіх викладачів

16

Re: Динамічна типізація в C++

pika1989 написав:

koala, я Вам дякую за пояснення, але мені не зовсім зрозуміло як бути в моєму випадку...
Тобто, можна зробити щоб у класі Підрозділ був масив об'єктів Працівник, а у класі Працівник достатньо лише назву підрозділу типу string?

Треба, щоб була можливість з підрозділу отримати список (наприклад, масив) працівників (чи посилань на них), а з працівника - назву підрозділу. Тобто мають бути, наприклад, такі функції:

vector<Worker *>& Department::getWorkers();
string& Worker::getDepartmentName();

Але, можливо, краще другу замінити на

Department* Worker::getDepartment();

і щоб вже з цього підрозділу отримували його назву, це просто логічно, правда? Тобто "отримати з працівника назву підрозділу" - це "отримати з працівника підрозділ" та "отримати з підрозділу назву", на кшталт

worker->getDepartment()->getName();

А всередині краще зберігати посилання (чи навіть shared_ptr, тут вже досить складна структура).

Подякували: pika19891

17

Re: Динамічна типізація в C++

FakiNyan написав:
koala написав:
FakiNyan написав:
Прихований текст

оце було б круто, якби у кожного викладача був би документ, котрий засвідчував його лвл. Типу, викладач 80 лвла, і щоб викладач з вищим лвлом міг відміняти або змінювати завдання дані викладачем нижчого лвла.

Це зветься "посада", декан може скасувати рішення викладача :)

декан не може розбиратись у всьому краще за всіх викладачів

Але може призначити комісію на час відсутності принципового викладача. І в комісію він входить.