How to best use an abstract base class as an interface without duplicating sibling classes function overrides

StackOverflow https://stackoverflow.com/questions/18178613

Question

I have an abstract interface Person which is inherited by Customer and SalesPerson. Person contains pure virtual functions for every member function of the two derived classes that need to be called by each other through references to the base(polymorphism). This allows me to decouple my types right?

How do I stop my derived classes inheriting the pure virtual functions of the other derived classes and becoming abstract without mirroring the sibling classes overridden functions with dummy non-pure virtual functions throughout my derived classes?

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();
};
Was it helpful?

Solution

You can't. Once you define an abstract base class, you need to implement all the functions in it's descendants. Otherwise the compiler won't know what you want to do. Imagine:

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

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

With this code:

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

Now, p.doSales(); is a perfectly valid call, because you promised that any Person has a doSales() method right?

The only solution is to use empty methods instead of abstract ones:

class Person
{
public:
   virtual void beCustomer() {};
   virtual void doSales() {};
};
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top