3

Program below doesn't compile for obvious reasons:

#include <iostream>
using namespace std;

class A {
 public:
  A() { pVirt(); }
  virtual void pVirt() const = 0 { count<<"A::pVirt()"; }
};

int main() {
 A aObj;
 aObj.pVirt();
 reutrn 0;
}

Questions: 1. 0 in signature "virtual void pVirt() const = 0" means what?, Is this indicates NULL memory offset in vtable or just a syntax constraint?

  1. If 0 is NULL memory offset (if in case it is so) then why VC++ doesn't allow to specify another memory address, and is this the reason why we can't call pure virtual function from outside constructor (MAY BE because vtable is created after an object is fully constructed.)?
null
  • 777
  • 1
  • 7
  • 12

4 Answers4

5

0 in signature "virtual void pVirt() const = 0" means what?,

The part =0 is called pure-specifier. It makes the virtual function pure, and the class abstract.

A pure virtual function need not to have definition. You may optionally provide a definition outside the class, and a non-abstract derived class still has to override the function.

class A
{
 public:
     virtual ~A() {};
     virtual void f() =0;
};

void A::f() { std::cout << "A::f" << std::endl; } //optional

The definition of f doesn't make the class non-abstract, so you cannot create instance of A:

A a; //error - A is abstract

Moreover, the derive class has to override A::f in order to be non-abstract:

class B : public A {};

B b; //error : B is still an abstract class as it didn't override A::f

And

class C : public A { void f() {} };

C c; //okay : C override A::f

And derived class implementation may choose to call the base class implementation:

class D : public A { void f() {  A::f(); } }; //defaults to A::f

D d; //okay : D override A::f, but calls A::f internally

Hope that helps.

Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • 1
    your answer is a very complete explanation, that clears up what's with the optional declaration of a pure virtual function. Thanks! – Matei Suica Feb 06 '13 at 12:54
4

It’s just syntax to denote that the function is pure virtual. It has no actual meaning whatsoever. The C++ designers could just as well chosen to use pure or abstract in place of = 0. I suspect the only reason for not doing so was that they didn’t want to introduce a new reserved word into the language (since that breaks any existing code which already uses the newly reserved word as an identifier).

(It’s not necessary to make such a word reserved since it would be a context sensitive keyword, but the concept of context sensitive keywords has only recently entered mainstream usage, and this syntax is much older.)

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
2

The = 0 in the function declaration is just syntax: the two token sequence means that the function is pure, that's all. And you cannot replace either of the tokens with anything else: = 0L isn't legal, for example.

And the reason you're getting the error is simply because the syntax isn't allowed. For historical reasons, if nothing else. If you want to provide a definition for a pure virtual function, you must do it outside of the class.

And if you provide a definition for a pure virtual function, you can call it from the constructor; you just have to disactivate the virtual call mechanism; e.g. A::pVirt(). If the actual function call involves dynamic resolution, and the resolution results in a pure virtual function, it is undefined behavior, regardless of whether the function is defined or not. The motivation here is to allow you not to define it; normally, a virtual function must be defined, whether you call it or not, because the compiler must put its address in the vtable, and if it isn't defined, there is no address. Making the function pure virtual tells the compiler that it shouldn't put its address in the vtable. So you don't have to define it. But you may get surprises if you try to call the function through the vtable.

James Kanze
  • 150,581
  • 18
  • 184
  • 329
  • +1 nice answer. Just reread Scott Meyers's old [column](http://www.artima.com/cppsource/nevercall.html) on the intricacies of calling virtual functions in constructors: you were correct to point out the error in my now deleted answer (didn't provide added value to your answer). – TemplateRex Feb 06 '13 at 12:55
1

The = 0 after a virtual function means that "this is pure virtual function, it must be implemented in the derived function". As in your example, it's still possible to implement the function. It has no other meaning as such - and you can't use other numbers, addresses or anything else. You can have several functions with =0, and it will still be the same meaning.

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227