Как наилучшим образом использовать абстрактный базовый класс в качестве интерфейса, не дублируя переопределения функций родственных классов

У меня абстрактный интерфейс Person который наследуется Customer а также SalesPerson, Person содержит чисто виртуальные функции для каждой функции-члена двух производных классов, которые должны вызываться друг другом посредством ссылок на базу (полиморфизм). Это позволяет мне отделить мои типы правильно?

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

class Person {
public:
    virtual int const GetNumberOfPurchases() const = 0;
    virtual long const GetId() const = 0;
    virtual void AddPurchase() = 0;
    virtual void DisplayCustomerDetails() const = 0;
    virtual void DisplaySalesPersonStats() = 0;
    virtual void SetContact(Person * SalesP) = 0;
};

class SalesPerson: public Person {
private:
    long const id;                    // Assumption: Sales people never change their ID
    Person *bestCustomer;
    Person *worstCustomer;
    vector<Person *> v_Client;
    virtual int const GetNumberOfPurchases() const { return 0; }; // dummy to avoid inheriting pure virtual function
    virtual void AddPurchase() {}
    virtual void DisplayCustomerDetails() const {}
    virtual void SetContact(Person * SalesP) {}
public:
    SalesPerson();
    virtual ~SalesPerson(){};
    Person const *GetBestCustomer() const;
    Person const *GetWorstCustomer() const;
    virtual long const GetId() const { return id; }
    void DisplaySalesPersonStats();
    float const CalculateMeanAverageSales();
    void SignUpCustomer(Person * aCustomer);
    void RegisterSale(long customerId);
    void CalculateBestAndWorstCustomers();
    void DisplayClientList();
    long GenerateSalesPersonKey();
};

class Customer: public Person{
private:
    long ID;
    int birthYear;
    bool isCurrentMember;
    unsigned numberOfPurchases;
    const Person *contact;       // Assumption: Each Customer has a single assigned contact SalesPerson
    virtual void DisplaySalesPersonStats() {} // Dummy to avoid inheriting pure virtual from Person
public:
    Customer(const int aBirthYear);
    virtual ~Customer() {}
    virtual long const GetId() const;
    int const GetBirthYear() const;
    void SetBirthYear(int aBirthYear);
    bool const GetIsCurrentMember() const;
    void ToggleIsCurrentMember();
    virtual int const GetNumberOfPurchases() const;
    virtual void AddPurchase();
    virtual void DisplayCustomerDetails() const;
    virtual void SetContact(Person * SalesP);
    long GenerateCustomerKey();
};

1 ответ

Решение

Ты не можешь Как только вы определили абстрактный базовый класс, вам нужно реализовать все функции в его потомках. В противном случае компилятор не будет знать, что вы хотите сделать. Представить:

class Person
{
public:
   virtual void beCustomer() = 0;
   virtual void doSales() = 0;
};

class Customer : public Person
{ 
public:
   virtual void beCustomer() { doStuff(); }
}

С этим кодом:

Person* p;
p = new Customer();
p.doSales();

Сейчас, p.doSales(); это совершенно действительный звонок, потому что вы обещали, что любой Person имеет doSales() метод правильно?

Единственное решение - использовать пустые методы вместо абстрактных:

class Person
{
public:
   virtual void beCustomer() {};
   virtual void doSales() {};
};
Другие вопросы по тегам