Polymorphism and non-virtual derived class methods

Consider the following code:

class Human
{
    virtual void Walk() = 0;
}

class Male : public Human
{
    void Walk();
}

class Female : public Human
{
    void Walk();
    Human* GiveBirth();
}

int main()
{
    vector<Human*> people;
    people.push_back(new Female);
}

Let's say I want to call GiveBirth() from the base class pointer, I would have these options:

1- Cast the pointer to the derived type

people.push_back( dynamic_cast<Female*>(people[0])->GiveBirth() );

Reason why I don't use it:

I need to make my program in a way that all derived classes are unknown by the user/programmer (even if it's logical to say that such a method is female related).

2- Make GiveBirth() method virtual

Reason why I don't use it:

This method would now be visible to Male class, which is everything but logical.

3- Use the 'Curiously Recurring Template Pattern'

Reason why I don't use it:

I don't know. Maybe I'm wrong with the usage of this pattern, but I think I could not create a global pointer to instantiate my derived classes since the base class is a template and it needs to know the type at compile time.

Is there any other program structure that could do what I want to achieve?

Upvotes: 2

Views: 228

Answers (1)

egur
egur

Reputation: 7970

Functions in the base class should not be aware of functions in their derived classes or their behavior unless of course that functionality is required by the base class and the base class in return declares them as virtual or pure virtual. In other words, the base class doesn't depend on the derived class. Code that does this create a circular dependency which should be avoided at all cost.

This means that you should declare or implement all the functions in the base class. If implemented, have them return an error (or throw an exception) so a derived class can override them with a proper implementation.

These functions in the base class will be virtual or pure virtual (preferred).

Example:

class Human
{
    virtual void Walk() = 0;
    Human* GiveBirth()  = 0;
}

class Male : public Human
{
    void Walk();
    Human* GiveBirth() { return NULL; }
}

class Female : public Human
{
    void Walk();
    Human* GiveBirth();
}

Upvotes: 0

Related Questions