Re: Applying contracts to abstract base class?

From: Daniel T. (postmaster_at_earthlink.net)
Date: 10/27/03


Date: Mon, 27 Oct 2003 14:18:30 GMT

kk_oop@yahoo.com (Ken) wrote:

> Hi. I'm looking to find a way to apply Design by Contract in my C++
> programs.
>
> The problem that I'm having deals with interface base classes (a base
> class with only pure virtual methods). Since these are often how an
> object gets exposed to clients via polymorphism, it seems critical
> that an abstract base class can define and enforce its contracts.
> Defining contracts is critical, so LSP can
> be utilized when defining derived implementation classes. However, if
> the interface base class defines a method to enforce its contract, it
> will no longer be an abstract interface. This poses a problem, for
> instance, if the abstract class is being used to apply multiple
> interface inheritance. In that case, the abstract class really needs
> to be pure abstract, otherwise it will result in having multiple
> implementation inheritance, which, in C++, is a risky, undesireable
> design.

This isn't an issue if the base class has no data.

> Is there a way for C++ to somehow enable an interface base class to
> enforce its contracts? Seems like an unfixable paradox.

The standard way to set up DbC in C++ is something like:

class Base {
public:
   void method() {
      // check preconditions
      do_method();
      // check postconditions
      invariant();
   }
private:
   virtual void do_method() = 0;
   virtual void invariant() {
      // check invariants
   }
};

class Derived {
private:
   void do_method() {
      // do work
      // check extra postconditions
   }
   void invariant() {
      Base::invariant();
      // check more invariants
   }
};

The biggest problem with this method is that it doesn't allow derived
class methods to loosen preconditions and it requires the derived class
designer to explicitly call the base classes invariants from within its
invariant.

Why is it such a pain to do DbC in C++? Mr. Stroustrup makes it clear in
"The C++ Programming Language" that he doesn't find much use in
expressing pre and post-conditions in the language itself, and not much
more use in expressing invariants. He recommends using comments for
pre/post-conditions and a simple 'check' function in the concrete class
for the invariant.

More information can be found in "C++ FAQs" by M. Cline.