1

I am working with a code and I saw something odd, a method of a class "MyClass" let's call it X() :

virtual void X() = 0;

So MyClass is an abstract class and in MyClass.cpp X() has a proper implementation... In derived classes of MyClass, this method is called via MyClass::X();

I thought that = 0 would invalidate its implementation... but it's not the case and it is, in fact, usable in derived classes.

Can you please tell what the compiler really do when he encounters = 0 ?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Aminos
  • 754
  • 1
  • 20
  • 40
  • 2
    Relevant: [Why does it make sense to give definition for a pure virtual function?](http://stackoverflow.com/questions/12918637/why-does-it-make-sense-to-give-definition-for-a-pure-virtual-function) – cpplearner Jan 27 '16 at 10:28
  • You can't instanciate MyClass because you tell X is not defined, and that it has to be implemented in child class (it's called an abstract class in lots of languages). – Pierre Emmanuel Lallemant Jan 27 '16 at 10:28
  • 5
    Your answer is here : http://stackoverflow.com/questions/2089083/pure-virtual-function-with-implementation – dkg Jan 27 '16 at 10:28

4 Answers4

2

From the standard (9.2 Class members [class.mem]):

= 0 is the pure-specifier

It tells that compiler that:

  1. the class is abstract
  2. the method will be defined outside the class definition (usually in a derived class)

Example 1 (build fails)

If I understand your question correctly, you have something like that:

class MyClass {
public:
    virtual void X() = 0;
};

class MyDerivedClass : MyClass {
public:
    virtual void X();
};

void MyDerivedClass::X() { MyClass::X(); }

int main()
{
    MyDerivedClass mdc;
    mdc.X();

    return 0;    
}

If so, the build should fail with:

Error:

undefined reference to 'MyClass::X()'

Example 2 (build succeeds)

However, even if the method MyClass::X() is declared as pure virtual, you can provide a definition. The following would work. The class MyClass is still abstract, but you can call the method MyClass::X().

#include <iostream>

class MyClass {
public:
    virtual void X() = 0; // pure virtual method
};

class MyDerivedClass : MyClass {
public:
    virtual void X();
};

void MyClass::X() {       // pure virtual method definition
    std::cout << "MyClass::X()" << std::endl;
}

void MyDerivedClass::X() {
    MyClass::X();
    std::cout << "MyDerivedClass::X()" << std::endl;
}  

int main()
{
    MyDerivedClass mdc;
    mdc.X();

    return 0;    
}

Output:

MyClass::X()
MyDerivedClass::X()
sergej
  • 17,147
  • 6
  • 52
  • 89
2

The =0 thing tells the compiler two things:

  1. A regular out-of-class function definition is not required (though allowed). If there is no such definition, and the function is actually called, this is a runtine error.
  2. The class is abstract and cannot be instantiated, whether a definition from point 1 is present or not. Attempts to do so should be flagged as compile time errors. Derived classes that don't override the function are abstract too.
n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243
0

You could not create instance of class with pure virtual methods, but in some cases you can call pure virtual methods, and it will be an error

Jeka
  • 1,364
  • 17
  • 33
0

I think the compiler creates a vtable with NULL pointers for pure virtual methods.

Ilan Kutsman
  • 469
  • 3
  • 9