tags:

views:

340

answers:

7

Hi,

My basic understanding is that there is no implementation for a pure virtual function, however, I was told there might be implementation for pure virtual function.

class A {

virtual void f() = 0;

};

void A::f() {

cout<<"Test"<<endl;
}

Is code above OK?

What's the purpose to make it a pure virtual function with an implementation?

+5  A: 

If you have code that should be executed by the deriving class, but you don't want it to be executed directly -- and you want to force it to be overriden.

Your code is correct, although all in all this isn't an often used feature, and usually only seen when trying to define a pure virtual destructor -- in that case you must provide an implementation. The funny thing is that once you derive from that class you don't need to override the destructor.

Hence the one sensible usage of pure virtual functions is specifying a pure virtual destructor as a "non-final" keyword.

The following code is surprisingly correct:

class Base {
public:
  virtual ~Base() = 0;
};

Base::~Base() {}

class Derived : public Base {};

int main() { 
  // Base b; -- compile error
  Derived d; 
}
Kornel Kisielewicz
Base class destructors are always called anyway, virtual or not and pure or not; with other functions you can't guarantee that an overriding virtual function will call the base class implementation whether or not the base class version is pure.
Charles Bailey
That code is wrong. You must define the dtor outside of the class definition due to a syntax quirk of the language.
Roger Pate
@Roger : thanks, that actually helped me -- this is the code I've been using, it compiles fine under MSVC, but I guess it wouldn't be portable.
Kornel Kisielewicz
+7  A: 

The advantage of it is that it forces derived types to still override the method but also provides a default or additive implementation.

JaredPar
+12  A: 

A pure virtual function must be implemented in a derived type that will be directly instantiated, however the base type can still define an implementation. A derived class can explicitly call the base class implementation (if access permissions are allow it) by using a fully-scoped name (by calling A::f() in your example - if A::f() were public or protected). Something like:

class B : public A {

    virtual void f() {
        // class B doesn't have anythign special to do for f()
        //  so we'll call A's

        // note that A's declaration of f() would have to be public 
        //  or protected to avoid a compile time problem

        A::f();
    }

};

The use case I can think of off the top of my head is when there's a more-or-less reasonable default behavior, but the class designed wants that sort-of-default behavior to be invoked only explicitly. It can also be the case what you want derived classes to always perform their own work but also be able to call a common set of functionality.

Note that even though it's permitted by the language, it's not something that I see commonly used (and the fact that it can be done seems to surprise most C++ programmers, even experienced ones).

Michael Burr
My thoughts exactly... except stated much more eloquently than I would have.
Dan
+1  A: 

Yes this is correct. In your example, classes that derive from A inherit both the interface f() and a default implementation. But you force derived classes to implement the method f() (even if it is only to call the default implementation provided by A).

Scott Meyers discusses this in Effective C++ (2nd Edition) Item #36 Differentiate between inheritance of interface and inheritance of implementation. The item number may have changed in the latest edition.

Yukiko
+5  A: 

To be clear, you are misunderstanding what = 0; after a virtual function means.

= 0 means derived classes must provide an implementation, not that the base class can not provide an implementation.

In practice, when you mark a virtual function as pure (=0), there is very little point in providing a definition, because it will never be called unless someone explicitly does so via Base::Function(...) or if the Base class constructor calls the virtual function in question.

Terry Mahaffey
This is incorrect. If you invoke that pure virtual function at the constructor of your pure virtual class, a pure virtual call would be made. In which case you better have an implementation.
rmn
@rmn, Yes, you are right about virtual calls in constructors. I updated the answer. Hopefully everyone knows not to do that, though. :)
Terry Mahaffey
In fact, making a base pure call from a constructor results in implementation-defined behavior. In VC++, that amounts to a _purecall crash.
Ofek Shilon
+1  A: 

You'd have to give a body to a pure virtual destructor, for example :)

Read: http://cplusplus.co.il/2009/08/22/pure-virtual-destructor/

rmn
A: 

Pure virtual functions with or without a body simply mean that the derived types must provide their own implementation.

Pure virtual function bodies in the base class are useful if your derived classes wants to call your base class implementation.

Brian R. Bondy