Coding standards

General Object-Oriented design principles you should try to follow:
  1. Identify the aspects of your application that vary and separate them from what stays the same;
  2. Program to an interface, not an implementation;
  3. Favor composition over inheritance;
  4. Strive for loosely coupled designs between objects that interact;
  5. Classes should be open for extension, but closed for modification;
  6. Depend upon abstractions. Do not depend upon concrete classes;
  7. Principle of Least Knowledge. Talk only to your immediate friends;

[SA04][CGL98][Cli]

Including header files

Do not include header files unnecessarily. Even if PCMSolver is not a big project, unnecessary include directives and/or forward declarations introduce nasty interdependencies among different parts of the code. This reflects mainly in longer compilation times, but also in uglier looking code (see also the discussion in [Sut99]).

Follow these guidelines to decide whether to include or forward declare:
  1. class A makes no reference to class B. Neither include nor forward declare B;
  2. class A refers to class B as a friend. Neither include nor forward declare B;
  3. class A contains a pointer/reference to a class B object. Forward declare B;
  4. class A contains functions with a class B object (value/pointer/reference) as parameter/return value. Forward declare B;
  5. class A is derived from class B. include B;
  6. class A contains a class B object. include B.
#ifndef MYCLASS_HPP
#define MYCLASS_HPP

//==============================
// Forward declared dependencies
class Foo;
class Bar;

//==============================
// Included dependencies
#include <vector>
#include "Parent.hpp"

//==============================
// The actual class
class MyClass : public Parent // Parent object, so #include "Parent.h"
{
  public:
    std::vector<int> avector; // vector object, so #include <vector>
    Foo * foo;                // Foo pointer, so forward declare
    void Func(Bar & bar);     // Bar reference as parameter, so forward declare

    friend class MyFriend;    // friend declaration is not a dependency
                              //    don't do anything about MyFriend
};

#endif // MYCLASS_HPP

Proper overloading of operator<<

Suppose we have an inheritance hierarchy made of an abstract base class, Base, and two derived classes, Derived1 and Derived2. In the Base class header file we will define a pure virtual private function printObject and provide a public friend overload of operator<<:

#include <iosfwd>

class Base
{
  public:
    // All your other very fancy public members
    friend std::ostream & operator<<(std::ostream & os, Base & base)
    {
            return base.printObject(os);
    }
  protected:
    // All your other very fancy protected members
  private:
    // All your other very fancy private members
    virtual std::ostream & printObject(std::ostream & os) = 0;
}

The printObject method can also be made (impure) virtual, it really depends on your class hierarchy. Derived1 and Derived2 header files will provide a public friend overload of operator<< (friendliness isn’t inherited, transitive or reciprocal) and an override for the printObject method:

#include <iosfwd>

#include "Base.hpp"

class Derived1 : public Base
{
  public:
    // All your other very fancy public members
    friend std::ostream & operator<<(std::ostream & os, Derived1 & derived)
    {
      return derived.printObject(os);
    }
  protected:
    // All your other very fancy protected members
  private:
    // All your other very fancy private members
    virtual std::ostream & printObject(std::ostream & os);
}

class Derived2 : public Base
{
  public:
    // All your other very fancy public members
    friend std::ostream & operator<<(std::ostream & os, Derived2 & derived)
    {
      return derived.printObject(os);
    }
  protected:
    // All your other very fancy protected members
  private:
    // All your other very fancy private members
    virtual std::ostream & printObject(std::ostream & os);
}

Code formatting

We conform to the so-called Linux (aka kernel) formatting style for C/C++ code (see http://en.wikipedia.org/wiki/Indent_style#Kernel_style) with minimal modifications. If uncertain on your code formatting use the Artistic Style command-line utility to rectify it:

astyle --style=linux --max-code-length=85 --indent-namespaces --keep-one-line-blocks filename