5

If I have a base class as so:

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

Now if I derive any class out of Base class, it will have to override foo().

What if I wanted a behavior on foo() for Base class too? So that base class has it's own foo, and on top of that, every single one of it's has to override foo? Is that possible?

  • So you still want to be able to instanciate the base class, but if you derive a sub class, you want to be sure that the sub class overrides the method, right? – Andreas Fester Nov 27 '12 at 20:29
  • @Mahi: Could you provide a bit more context (a real-world example maybe?) as to why you need to do what you are suggesting? While writing my answer, I tried to imagine of one but couldn't. – Miltos Kokkonidis Nov 27 '12 at 22:41
  • While doing so will not change the answer (you can do things close to what you want, but not exactly what you want :-( ) it will be of benefit to those of us that scratched our heads and wondered if you have uncovered something useful that C++'s design left out. – Miltos Kokkonidis Nov 27 '12 at 23:20

2 Answers2

7

If you do something like:

class Base {
    public:
        Base(){}
        virtual void foo() = 0;
};
void Base::foo() {
{ 
     cout << "Hello";
}

you will get an abstract class, so you will not be able to create an object b of class Base and have it use your implementation of foo() by invoking b.foo().

So this is not what you want! The next question is why were you allowed to provide an implementation for Base::foo if you cannot ever use it. Well, actually you can! Not directly though.

class Deriv : public Base {
    public:
        Deriv(){}
        virtual void foo();
};
void Deriv::foo() 
{ 
     Base::foo(); cout << "  world!";
}

As you can see Base::foo() can be used by the derived classes.

Back to your question. The answer is you can do exactly what you specified, except that the Base class will be abstract.

The alternative is to do what most people do and not specify =0 when you give an implementation for foo() in Base. This means that derived classes can override foo() but do not have to. This actually seems to me to make perfect sense: in derived classes for which Base::foo()'s default implementation makes sense, you keep it, but for those that need something different you override it.

Update: I tried to come up with a scenario that actually requires what the questions is asking about and came up with this:

Imagine that Document and its derived classes represent document types and that Document contains a virtual method getClassIcon() returning the URL for the image file for the icon that represents the document type. It makes sense for Document to have an icon (something representing a generic document) and it also makes sense to require all derived classes to override getClassIcon() in order to provide their own icons.

Having said that, in this particular example it seems easy to find an alternative design: make Document::getClassIcon() a pure virtual method (=0) (making Document an abstract class) and add OtherDocument as one of its derived classes, giving it the implementation of getClassIcon Document had previously. PDFDocument, MSWordDocument etc will all be required to override getClassIcon() as required. What this re-design might be taken to reveal is that the previous design (supported by an imaginary version of C++ that allows what the question is asking for) had conflated the role of the base class, Document, and the role of a class standing for the documents that do not belong to any of the known types, OtherDocument. It is all in the eye of the beholder of course :-) One may argue that the second design was merely necessary because of functionality missing from the language. I guess we think (to a large extent) according to the (computer) language we speak. :-)

Miltos Kokkonidis
  • 3,888
  • 20
  • 14
  • Yeah I figured your "update" way already few days ago, and it's what I've been using. Was just wondering if there's an other way too, where I don't need an extra class. But I guess there's no other way, I'll just accept your answer even tho it didn't quite help me, but it's still correct :) –  Nov 28 '12 at 16:06
  • 1
    @Mahi Well, exchanging ideas is always good, even if it turns out two people had the exact same idea. Thanks for accepting the answer and good luck with your project. – Miltos Kokkonidis Nov 29 '12 at 11:39
4

You could provide an implementation for the pure virtual method:

class Base {
  ...
  virtual void foo()=0;
}

void Base::foo() {
     ... implementation goes here ...
}

The class remains abstract. If you don't want it abstract, you have to remove the =0. However, once you do that, you can't force the derived classes to provide their own implementations.

In other words, you have to make a choice.

NPE
  • 486,780
  • 108
  • 951
  • 1,012
  • Edit: had a typo, but got different error now `error: pure-specifier on function-definition` –  Nov 27 '12 at 20:22
  • Just curious... If we cannot instantiate abstract classes and want to force the derived classes to provide their own implementations then why provide an implementation for the pure virtual method? – Sidharth Mudgal Nov 27 '12 at 20:27
  • @SidharthMudgal: The most common use case is probably pure virtual destructors. See http://stackoverflow.com/questions/1219607/why-do-we-need-a-pure-virtual-destructor-in-c – NPE Nov 27 '12 at 20:29
  • So it's either abstract OR not forcing implementations... Seems stupid, but I guess I'll have to deal with it. –  Nov 27 '12 at 20:31
  • 2
    @NPE http://stackoverflow.com/questions/2951273/pure-specifier-on-function-definition – Andreas Fester Nov 27 '12 at 20:57