C++ (and C) Interfaces

Practical 101

Created by Wojciech Migda

Literature

  • Radford, M. C++ Interface Classes - An Introduction, Overload 62, 2004, 21.
  • Navia, J. A container library for C, ISO/IEC JTC1/SC22/WG14 - C, N1625, 2012.
  • Griffiths, A. Radford, M. Separating Interface and Implementation in C++, Overload 66, 2005, 16.
  • Radford, M. C++ Interface Classes - Noise Reduction, Overload 68, 2005, 6.

C++ interface class

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

C++ interface class

destructor?

C++ interface class

destructor?

  • yes,
  • virtual and public.

C++ interface class

constructor?

C++ interface class

constructor?

  • default,
  • leave it to the compiler.

C++ interface class

copy operator?

C++ interface class

copy operator?

  • no,
  • disabled (private and undefined)

C++ interface class

class I {
public:
  // default constructor
  virtual void foo(void) = 0;
  virtual ~I(void){}
private:
  I& operator=(const I &);
};

C++ implementation class

class D : public I {
//[access-specifier]:
  virtual void foo(void){}
};

C++ implementation class

destructor?

C++ implementation class

destructor?

  • yes,
  • virtual and public.

C++ implementation class

constructor?

C++ implementation class

constructor?

  • yes,
  • public,
  • explicitly calls interface class constructor.

C++ implementation class

interface methods' access?

C++ implementation class

interface methods' access?

  • private.

C++ implementation class

class D : public I {
public:
  D() : I() {}
  virtual ~D(void){}
private:
  virtual void foo(void){};
};

C++ factory

where?

C++ factory

where?

  • separate free function.

C++ factory function

what should it return?

C++ factory function

what should it return?

  • raw pointer,
  • smart pointer with ownership transfer (std::auto_ptr, std::unique_ptr),

C++ factory function

std::unique_ptr<IFileObject> createFileObject(const std::string & in_path);
we can do better than that..

C++ factory function

class IFileObject {
public:
typedef std::unique_ptr<IFileObject>    ptr;
...
};

IFileObject::ptr createFileObject(const std::string & in_path);

C interface

Boundaries of the interface will be emphasized by using a struct of function pointers.

struct tagListInterface {
  int (* const Add)(List * L, const void * newval);
  int (* const Clear)(List * L);
  int (* const Contains)(const List * L, const void * element);
//...
};

C interface

Interface structure is either a global variable or its pointer is returned by a factory function.

struct tagListInterface const * iList(void);
//...
iList()->Clear(list_ptr);

C interface

We can even introduce polymorphism and private interface by means of VTable pointer:

struct _List {
  ListInterface *  VTable;
  list_element *   Last;
  list_element *   First;
  //...
};

C interface "polymorphism"

void test_1(void) {
  struct Mock {
    static int empty(ListCPtr self) { return 0; }
  } mock;

  struct ListInterface interface = {0, 0, mock.empty, 0};
  ListPtr list_p = give_random_list();
  list_p->vTable = &interface;
  // do the test
}

C interface "polymorphism"

int empty(ListCPtr self) {
  int result;
  if (self->vTable->empty && self->vTable->empty != empty) {
    result = self->vTable->empty(self);
  }
  else {
    result = empty_impl(self);
  }
  return result;
}

THE END

BY Wojciech Migda

Q&A