1

I am a beginner in C++ object oriented programming. I was studying "Abstract Classes" where the example code is:

#include <iostream>
using namespace std;

class Enemy {
    public:
        virtual void attack() = 0;
};

class Ninja: public Enemy {
    public:
        void attack() {
            cout << "Ninja!"<<endl;
        }
};

class Monster: public Enemy {
    public:
        void attack() {
            cout << "Monster!"<<endl;
        }
};


int main()
{
    Ninja n;
    Monster m;
    Enemy *e1 = &n;
    Enemy *e2 = &m;

    e1->attack();
    e2->attack();

    return 0;
}

What I want to understand is why can't I just use the objects of derived classes to access directly the derived class members with "." operator (It works, but it is not advised why?).

Like this:

int main()
{
    Ninja n;
    Monster m;
    Enemy *e1 = &n;
    Enemy *e2 = &m;

    //e1->attack();
    //e2->attack();
    n.attack();
    m.attack();

    return 0;
}

I know there will be situations where we need to go through the base class to access the members of derived classes (I think this is the normally used by all the programmers), but I have no idea on real world implementation of that kind of cases (Why can't we go direct, why is through pointers of base class?).

I would be very glad if someone can clarify my doubt.

  • Possible duplicate of [Why do we need abstract classes in C++?](http://stackoverflow.com/questions/14189438/why-do-we-need-abstract-classes-in-c) – Andy Thomas Apr 12 '17 at 17:41
  • You need a deeper example. Say you have functions to perform tasks on enemies. You would not want to write the same function over and over with one for `Ninja`s, one for `Monster`s, one for `Unicron`, etc... – user4581301 Apr 12 '17 at 17:42
  • @AndyThomas...Give me some time. I will understand the concept and if they both seem same, I will delete my question. Thanks. – 14yearoldprogrammer Apr 12 '17 at 17:47
  • @14yearoldprogrammer - You don't need to delete your question. Marking a question a duplicate just stops additional work from being put into a question that already has an answer. – Andy Thomas Apr 12 '17 at 17:58

2 Answers2

4

A collection of enemies (std::vector<Enemy*>) can have ninjas and monsters. A collection of ninjas can only contain ninjas, and a collection of monsters can only contain monsters.

An abstract base class provides a common interface for child classes to implement, but where an instance of the abstract base class has no practical meaning (otherwise you would not make the base class abstract).

crashmstr
  • 28,043
  • 9
  • 61
  • 79
  • 1
    Note, you can also implement more types of enemies down the road with their own custom behavior, without having to change anything that was written using the common Enemy interface. – Christopher Pisz Apr 12 '17 at 17:42
0

The rest of this has been covered well buy the other answers, but "Why a pointer?" has been ignored.

Each of the subclasses have a different contents and likely different sizes. Without a reference, the program would have to know the exact size to allocate storage. Mandating that all subclasses be the same size is a non-starter as this flies in the face of the C++ ideology of only paying for what you use and would require modification to previously compiled code (a new module adds a new subclass, all existing modules would have to change as well). Further, there is no reasonable way for a base class to know details about its subclasses (And many reasons why it shouldn't) and this includes knowing the size.

With a reference, no one cares about about the size or implementation details. The object is some anonymous blob of memory of unknown size that contains its own access rules and instructions if the object is polymorphic (This is probably a "v-table", but C++ doesn't care what voodoo is used so long as the results meet the Standard).

Community
  • 1
  • 1
user4581301
  • 33,082
  • 7
  • 33
  • 54