2

I have a basic base class and a couple of sub-classes which inherit from it.

Class Base{
public:
   Base(){};
   virtual ~Base();
   virtual void foomethod()=0; //Marked as pure virtual
};

Class A : public Base{
   A(){};  //Ctor
   ~A(){}; //Dtor
   void foomethod(){ /* DO SOMETHING */ }
}
Class B : public Base{
   B(){};  //Ctor
   ~B(){}; //Dtor
   void foomethod(){ /* DO SOMETHING */ }
}

Use of the above is throwing an error in the following usage:

Base a = A();
Base b = B();

The compiler is complaining about the function foomethod() being pure virtual.

However, when the following is used, there is no problem.

A a = A();
B b = B();

I would have thought that the first instance should be accepted due to C++'s principles of polymorphism. I want to enforce a specific method implementation of the method in sub-classes. If it is marked as virtual only, there is not guarantee that it will be explicitly overrided.

Nicholas Hamilton
  • 10,044
  • 6
  • 57
  • 88
  • 1
    First, that easily leads to slicing. Second, you can't create an object of an abstract base class. – chris Jun 22 '14 at 07:48
  • 1
    You can't instantiate an object with a pure method directly (no code for that). And virtual polymorphism works with pointers, see the slicing problem here as chris noted – Marco A. Jun 22 '14 at 07:50
  • Useful text on SO about this problem: http://stackoverflow.com/questions/274626/what-is-the-slicing-problem-in-c – Ilya Jun 22 '14 at 07:51
  • 1
    @MarcoA., Pointers and references. – chris Jun 22 '14 at 07:57
  • @chris Right, thanks! They also use pointers internally (but that is hardly something relevant here) – Marco A. Jun 22 '14 at 08:00

1 Answers1

3

There are several issues with your code, I'll try to get most of them:

  1. You can't have a pure function without marking it as virtual

  2. You can't create objects of an abstract Base class (there's no code for the methods)

  3. When you write

    Base b = A();
    

    you're creating two objects and then assigning the A object to the Base b object. This cannot happen since Base is abstract but in cases where this can happen you could experience the slicing problem.

  4. You marked the destructor as virtual in the derived classes but not in the Base (and no definition either), always mark it as virtual when using virtual polymorphism otherwise derived destructors will not be called

This is a more correct way of doing it:

#include <iostream>
using namespace std;

class Base{
public:
   Base(){};
   virtual ~Base() {};
   virtual void foomethod()=0; //Marked as pure virtual
};

class A : public Base{
public: 
   A(){};  //Ctor
   virtual ~A(){}; //Dtor
   void foomethod(){ cout << "Hello from A"; }
};
class B : public Base{
public:
   B(){};  //Ctor
   virtual ~B(){}; //Dtor
   void foomethod(){ /* DO SOMETHING */ }
};

int main() {

    // Base obj; // Can't do that
    Base *obj = new A();
    obj->foomethod(); // A's one
    delete obj;

    return 0;
}

http://ideone.com/gvcL9S

Oh and there were some syntax errors here and there.. and a visibility problem if you intend to use those functions from the outside.. but I believe the excerpt was just a pseudocode one.

Community
  • 1
  • 1
Marco A.
  • 43,032
  • 26
  • 132
  • 246
  • FWIW, you could implement `foomethod` so there is code for it and still not be able to succeed :) – chris Jun 22 '14 at 08:08
  • 1
    Would be better if the solution didn't rely on error-prone new and delete. Unfortunately pointers are polymorphic but objects aren't. The answer might be found in something templated. – david.pfx Jun 22 '14 at 14:33
  • @RafaelCamposNunes: I think that would just drift even further away from the purpose of the original question. – david.pfx Jun 19 '18 at 01:16