C++ Proposal : Interfaces

Original Authour : Christopher Diggins
Date of Original Proposal : April 13, 2004
Last Modification : Friday October 29, 2004
This proposal is not being actively pursued at the following time by the original authour. Feel free to expand and modify this work as long with proper credit given to the original authour.

Motivation #1 - Interfaces without Virtual Functions

  1. Problem

    Interface constructs are used to model looks-like and behaves-like object relationships. C++ does not support interfaces.

  2. Common Workaround

    What is typically used to compensate for this deficiency are abstract base classes (classes with one or more pure virtual functions) commonly referred to as ABC's.
  3. Deficiency of Common Workaround

    The principal problem of using an ABC as an interface is that it requires the declaration of functions intended to model the interface as virtual. This is uneccessary and incorrect with regards to the intuitive definition of an interface. This also leads to two major practical problems:
    1. ) performance penalties due to superflous dispatching and inability of the compiler to inline calls where normally it would be appropriate.
    2. ) object size penalties which increase linearlu with the number of interfaces modeled due to extra vtable pointers within the objects.
    The second problem is especially troublesome because design models that use interfaces typically call for multiple interfaces, thus compounding the penalties, and making many perfectly acceptable object oriented designs unusable in practice.
  4. Writing out Interfaces Manually

    Given that the common solution of using ABC's to emulate interfaces may be deemed unacceptable for various reasons, the programmer is left with the alternative of writing their own interface types. This requires a significant amount of coding and is a complex endeavour. The redundnacy of typing can be overcome to a certain degree through the clever use of macros. The macro approach is often considered an undesirable solution for many reasons which leaves us in a position to consider a propsal for a change to the language.

Motivation #2 - Template Parameter Requirements Checking

  1. Problem

    As outlined in Stroutstrup 2003, Concept Checking - A more abstract compliment to type checking ( http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1510.pdf ) C++ lacks a more general and abstract facility than type checking to express template parameter requirements. Interfaces are almost exactly the same as the function matching approach described in the Stoustrup paper, which he characterizes as being promising.

Description of Proposal for non-assignable interface variables

Interfaces are an excellent canidate for consideration as a new features for C++ language due the fact that the represent a clear and well-defined semantic construct with relatively low impact on other aspects of the language itself.
  1. Declaring Interfaces

    Allow declaration of an interface type, like a class/struct but with only function declarations, i.e.:
    
          interface IFuBar {
            void FuBar();
          };
        
  2. Interfaces Implementations

    Any object that has definitions for a complete set of functions with matching signatures as any given interface is said to implement that interface.
  3. Interface Variables

    An interface variable is a non-assignable variable that can refer to any object that implements that interface. An interface variable stores a pointer to an object that implements an interface. An interface variable allows any function that is part of the interface to be invoked using dot notation. It is the intention of this proposal that an interface variable model its behaviour as closely to reference type as can reasonably be expected.
  4. Constructing and Initializing Interface Variables

    Interface variables must be intialized with a variable which can either be an instance of a class or struct which implements the corresponding interface, or can be an interface variable of the same or derived type.
    
          SomeInterface i = x;
        
    Interpretation of the above statement:

  5. Assignment

    Interface variables can not be assigned to (i.e. treated as an l-value).
  6. Invalid interface variables

    If an interface variable's target object is invalidated (i.e. prematurely destroyed) then the interface variable exhibits undefined behaviour when a member function is invoked.

  7. Const Qualification

    Interface variables can be declared as const:
    
          const SomeInterface i = SomeObject;
        
    Const qualified interface variables behave like const references, only allow const member functions to be called, etc.
  8. Extending the Lifetime of temporaries

    Using an interface variable as an lvalue extends the lifetime of that temporary in the same way that assigning a temporary to a reference does.
  9. Typecasting Precedence

    A conversion from object to interface variable has precedence just above that of a user defined typecast, but less than all other conversions.
  10. dynamic_cast

    Interface variables can be cast to the type of object they refer to using dynamic_cast, this returns a type-safe pointer to the internal object.
  11. Interface Comparison

    An interface variable can be compared using == to another interface variable with the result being equivalent to a comparison of the internal object pointers.
  12. Interface Arguments to Template Parameters

    Parameters to templates can be restricted to only interface types through the following syntax:
    
          template<interface argument_name> // ...
        
  13. Visibility Modifiers

    All interfaces functions are always public therefore no visibility modifers are allowed.
  14. Inheritance

    An interface can inherit from one or more interfaces. Syntax of inheritance of interfaces is as follows:
    
          inheritance_list ::= interface_name [, interface_name]*
    
          interface inteface_name : inheritance_list {
            // ...
          };
        
    Notice that there are no qualifiers allowed before an interface name from the inheritance list. Interfaces only ever publically inherit from other interfaces. Classes or structs can not inherit from interfaces.
  15. Template Parameter Requirements Checking

    Interfaces would be an excellent construct for checking requirements on template parameters. This could easily be done in the following syntax:
    
          template<class T : SomeInterface> class SomeClass {
            // ...
          };
        
    This would mean that T is required to implement SomeInterface implicitly.