Определение методов в родительском классе для нескольких детей - PullRequest
1 голос
/ 25 октября 2019

У меня есть родительский класс Person, затем он наследуется Employee и Customer, и они наследуются далее. Также у меня есть массив Person указателей, где я храню классы "третьего уровня". Я бы хотел, чтобы salary() был доступен только для Employee с, а charge() только для Customer с. Пытался использовать чистые функции в Person, но тогда Employee и Customer все еще требуют, чтобы оба были определены для конструирования.

Может быть, я мог бы определить другим способом или каким-то образом заблокировать / удалить нежелательные функции у детей?

class Person {
public:
    int money;
    Person() { money = 1000; }
    virtual ~Person() {}
    void salary(int m) { if (m >= 0) money += m; }
    void charge(int m) { if (m >= 0) money -= m; }
};

class Employee : public Person {};
class Customer : public Person {};

class Programmer : public Employee {};
class Secretary  : public Employee {};
class Janitor    : public Employee {};
class Business   : public Customer {};
class Private    : public Customer {};
class Charity    : public Customer {};

Редактировать:

Person* people[10];
Person[0] = new Programmer();
...

Затем я хочу вызвать метод, используя эти указатели, например, (*person[0]).salary(100) для производных от Employee или (*person[5]).charge(500) для клиентов. Я использую приведение, чтобы узнать, если объект от E или C.

Ответы [ 2 ]

1 голос
/ 25 октября 2019

Я не уверен, что это сработает так, как вы просили, но я предоставлю вам решение:

class Person {
public:
    int money;
    Person() { money = 1000; }
    virtual ~Person() {}
};
// providing the methods as specialization to the Employee and Customer classes    
class Employee : public Person {
    public:
    void salary(int m) { if (m >= 0) money += m; }
};
class Customer : public Person {
    public:
    void charge(int m) { if (m >= 0) money -= m; }
};
class Programmer : public Employee {};
class Secretary  : public Employee {};
class Janitor    : public Employee {};
class Business   : public Customer {};
class Private    : public Customer {};
class Charity    : public Customer {};

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

Person* people[10];
people[0] = new Programmer();
// while accessing you need to make sure that it is type employee!!
if (auto employee = dynamic_cast<Employee*>(people[0])) {
    employee->salary(100)
}

Точно так же и для Клиента !!!

Не забудьте включить <typeinfo> для dynamic_cast !!

1 голос
/ 25 октября 2019

Это невозможно сделать во время компиляции из-за стирания типа, но вы можете сделать это во время выполнения.

Сначала определите функции в соответствующих классах вместо базового класса:

class Person {
    // no salary or change
};

class Employee : public Person {
public:
    virtual void salary(int m)
    {
        // ...
    }
};

class Customer : public Person {
public:
    virtual void change(int m)
    {
        // ...
    }
};

Тогда, если вы уже знаете, что Person* указывает на сотрудника, используйте static_cast:

static_cast<Employee*>(people[0])->salary(100);

Если вы не знаете, используйте dynamic_cast:

if (auto* employee = dynamic_cast<Employee*>(people[0])) {
    employee->salary(100);
} else {
    // report error
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...