16

I'm now learning C++, the OO side, and I see this all the time:

class SomeClass{
   virtual void aMethod()=0;
}

class AnotherClass{
   void anotherMethod(){/*Empty*/}
}

class SomeClassSon : public SomeClass{
   void aMethod(){/*Also Empty*/}
}

what is the difference between the 3 methods? The virtual equals zero, the empty one, and the virtual, since it is inherited, empty one.

Why can't I just make the SomeClassSon method like the father, virtual void equals zero?

Robert Houghton
  • 1,202
  • 16
  • 28
Afonso Tsukamoto
  • 1,184
  • 1
  • 12
  • 21

6 Answers6

19

For your

class SomeClass{
   virtual void aMethod()=0;
}

the presence of a pure virtual method makes your class abstract. Once you have one such pure virtual method, =0, in your class, you cannot instantiate the class. What is more, any derived class must implement the pure virtual aMethod(), or it becomes an abstract class as well.

In your derived class, you overwrite the pure virtual method from above, and this makes the derived class non abstract. You can instantiate this derived class.

But, in derived class, method's body is empty, right? That's why your question makes sense: why not make the class pure virtual as well. Well, your class may entail other methods. If so, SomeClass cannot be instantiated (there is a pure virtual method), whereas child class SomeClassSon can be.

Same applies to your AnotherClass, which can be instantiated, contrary to SomeClass.

kiriloff
  • 25,609
  • 37
  • 148
  • 229
7

The difference is that virtual void aMethod() = 0 is a pure virtual function, meaning that:

  1. SomeClass becomes an abstract base class, meaning it cannot be instantiated.
  2. Any class which inherits from SomeClass must implement aMethod, or it too becomes an abstract base class which cannot be instantiated

Note that any class with one or more pure virtual functions is automatically an abstract base class.

Charles Salvia
  • 52,325
  • 13
  • 128
  • 140
  • 1
    Maybe you meant the right thing, but said it wrong: classes deriving from `SomeClass` are *not* forced to implement the function, but if they don't they're abstract as well. – Arne Mertz Feb 25 '13 at 20:17
4

The "equals 0" you're referring to is called "pure virtual". It's a function that the child that wants to be instantiated HAS to implement as opposed to providing base functionality meaning that the parent class is going to define functionality that has to exist but that the parent has no knowledge of how the child will do it. Note that this makes the class abstract in that it cannot be instantiated. For example I may want to define a "Mammal" class I can inherit from and I want its children to act a certain way - but I can't simply make a "Mammal". Instead I would create a "Giraffe" class and make sure it acts like it's supposed to.

It's also explained at this SO question.

The "Empty" function you're referring to is instead functionality where the function is defined and can be called - but does nothing.

Community
  • 1
  • 1
McAden
  • 13,714
  • 5
  • 37
  • 63
3

the declaration aMethod()=0 tells the compiler that this method must be provided for in subclasses. Any subclass that does not implement the method can not be instantiated. This helps you ensure any objects of the base class will have the method implemented.

Joy
  • 321
  • 1
  • 9
2

A pure virtual function (your first example, with the =0) means that function must be overridden in a derived class for an object of that class to be instantiated.

The second is basically just a member function that does nothing. Since the function has a different name and the class isn't related to SomeClass, the two don't affect each other at all.

The third overrides the pure virtual function, so it's possible to instantiate SomeClassSon, but in the derived class the overridden function does nothing.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
1

A pure virtual makes the class abstract. An empty non-virtual method doesn't do anything - it just leads to a linker error if you attempt to call it. By contrast, you can't attempt to call a pure virtual (unless you attempt to call it from a constructor, which is bad anyway) because the compiler won't let you create that object.

There's also a logical difference - the method marked virtual will be virtual through the inheritance chain - the others are just regular methods.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625