-1

Consider a class that is supposed to offer some (polymorphic) methods such as arithmetic or bitwise operators for all its subclasses. These operations should NOT be modifiable by the derived classes to ensure correct execution. However, at the same time I would like to have the evaluation of subclasses (with the function isError() in my example) be individually defined:

class Mom
{
public:
    virtual bool operator && (const Mom&) const final
    {
        return this->isError() && p_rOther.isError();
    }
private:
    virtual bool isError() = 0;
};

This does not seem to be allowed given the current standard, as the "pure virtuality" implies the necessity for subclasses to implement all virtual functions of the baseclass, whereas the "final" keyword contradicts this paradigm.

Any suggestions or ideas how to handle this contradiction?

Grantly
  • 2,546
  • 2
  • 21
  • 31
gilgamash
  • 862
  • 10
  • 31
  • 2
    A pure virtual function must be overridden - that doesn't mean that any other virtual functions must be. – Mike Seymour Mar 16 '12 at 15:20
  • It is about mixing pure virtuality and "final" methods in one class. As isError() is pure virtual, I need to override all virtual methods of the classs, which does not work for the "final" oeprator. THat is the problem I am talking about. VS 2010 complained about this combination. I thought as Mike Seymour before, too, but MS VS did not compile this. – gilgamash Mar 16 '12 at 15:21
  • 1
    @gilgamash: "I need to override all virtual methods" - no, only the pure ones. – Mike Seymour Mar 16 '12 at 15:21
  • 1
    It's not a contradiction. The derived classes have to implement all *pure virtual* functions, but they don't have to reimplement other virtuals (unless they want to). – Bo Persson Mar 16 '12 at 15:22
  • OK, then I will check again if I made some kind of mistake. However, VS did not want to compile it. Thanks for your comments! – gilgamash Mar 16 '12 at 15:23
  • I have never seen a virtual method marked final in C++. In Java, yes. In fact, this probably doesn't even compile. –  Mar 16 '12 at 15:23
  • @MikeSeymour: Ah ok, just read it here.. I imagine the use case would be rare. http://www.learncpp.com/cpp-tutorial/b-6-new-virtual-function-controls-override-final-default-and-delete/ –  Mar 16 '12 at 15:28
  • Thanks for your comments, I found my problem and got mixed up with pure virtual methods and abstract classes. Problem resolved! – gilgamash Mar 16 '12 at 15:40
  • Another clue to the problem could be that VS 2010 has not properly implemented `final` yet, but calls it `sealed`. [C++ sealed and interface](http://stackoverflow.com/questions/1445662/c-sealed-and-interface) – Bo Persson Mar 16 '12 at 16:04
  • 2
    Never create your own `operator&&` because it changes the semantics of the operator (it no longer short-circuits once you create your own). – Mark B Mar 16 '12 at 16:08
  • 1
    @gilgamash please contribute with more detailed information regarding your problem, or mark one of the answers provided as accepted to notify future readers that this question has been solved. – Filip Roséen - refp Mar 20 '12 at 14:50

2 Answers2

5

I assume that you have been misinformed on how pure virtual member-functions are dealt with and what they are for.

Only member-functions declared to be pure virtual must be defined in the classes inheriting from your base.

I'm guessing you are confusing it with the fact that the whole Base will become abstract.


The snippet further down in this post works just fine, and results in the behavior that you have described. Though having a virtual function made final kind of defeats it's purpose.

I'd recommend you to remove the virtual specifier.

This is unless your Base is inheriting from a base where the virtual function is present and you'd like to make this clear to future developers reading your code.


#include <iostream>

struct Base {
  virtual bool operator&& (Base const& rhs) const final {
    std::cerr << "Base ::operator&& ()\n";

    return this->error () && rhs.error (); 
  }

  virtual bool error () const = 0;
};

struct Child : Base {
  virtual bool error () const {
    std::cerr << "Child::error ()\n";

    return true;
  }
};

int
main (int argc, char *argv[])
{

  Child ch1,   ch2;
  ;     ch1 && ch2;
}

output

Base ::operator&& ()
Child::error ()
Child::error ()
Filip Roséen - refp
  • 62,493
  • 20
  • 150
  • 196
  • Yep, thanks, I confused what you state. My bad, sorry for the inconvenience and thanks for the help! – gilgamash Mar 16 '12 at 15:40
  • @gilgamash don't forget to mark the answer as accepted if you are satisfied with the information provided, glad to be of service. – Filip Roséen - refp Mar 16 '12 at 15:40
  • `Only member-functions declared to be pure virtual must be overloaded in the classes inheriting from your base.` Overloaded, or *overridden*? – Dan Mar 17 '12 at 16:09
  • @Dan neither to be honest, I should have written "defined". thanks for the input, I'll correct the matter asap. (please remove your comment post-edit if your are satisfied, this is to not confuse future readers). Thanks. – Filip Roséen - refp Mar 17 '12 at 17:22
2

You seem to be mistaken about what a pure virtual function means.

the "pure virtuality" implies the necessity for subclasses to implement all virtual functions of the baseclass

No, the pure virtuality requires that a subclass overrides that particular function. Non-pure functions don't have to be overridden, and of course can't be if declared final.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644