FeatureC++ Syntax

Programming in FeatureC++ is not much different than programming in C++. Actually, programming in FeatureC++ is even simpler due to modifications of the C++ language. The following overview present FeatureC++ syntax and the modifications of the C++ syntax. Since FeatureC++ transforms source code into C++ code before compilation, any C++ compiler can be used.

The FeatureC++ Language

In order to cope with the requirements of FOP and to simplify software development there are some new language constructs in FeatureC++ and also some modifications of source code layout.

Features and Classes

FeatureC++ uses folders to represent features and a folder hierarchy can be used to represent a hierachy of features. Classes are implemented as in plain C++ but are naturally distributed over multiple features. For example, a class String, representing the implementation of a string with operations like concatenation, searching, etc. might be distributed over multiple features that implement these operations as shown below.

Each folder represents a feature and all files String.h, represent the implementation of a particular feature of that class (e.g., to search in a string). In contrast to plain C++, classes are completely implemented in header files.

Header Files and Includes

Since classes are distributed over different folders (representing features), all code belonging to a class is defined in multiple files. Writing include directives for each file is not possible because the actually available files in a compile process depend on the configuration. FeatureC++ thus helps the programmer and generates all required includes as well as forward declarations and thus simplifies the development process. The developer can thus use a class without writing the include. This also avoid unneeded includes where a forward declaration is sufficient. Includes for used C++ files have to be written as usual.

As another extension, it is not required to create preprocessor definitions to avoid recursive includes. Such definitions are also generated by FeatureC++.

New Keywords

C++ Extensions

In order to simplify programming and seamlessly integrate C++ and FOP, FeatureC++ also modifies the C++ syntax.

The super keyword

As in Java and other languages the super keyword can be used to call overridden virtual methods of base classes. That is, one does not have to write BaseClass::foo(); but only writes super::foo();. This avoids errors when changing the inheritance hierarchy and avoids problems when using the super keyword to call an overridden method in method refinements.

Mixins

FeatureC++ supports mixins for class composition. A mixin is an abstract subclass that may be used to specialize the behavior of a variety of parent classes [1]. This means that a mixin class, a small unit for reuse, can be applied to different classes for creating subclasses. Furthermore, the functionality of multiple mixins can be aggregated in a single class. A code example for mixins as they are used in FeatureC++ is shown below.

//a linked list
class List {
public:
    void add(Elem e) {     
        cout << "add";
    }
};

//a mixin class for synchronizing containers
class ContainerSync {
public:
    void add(Elem e) { 
        cout << "lock ";
        super::add(e);
        cout << " unlock";
    }
};

//applying the mixin to create a synchronized list
class SyncList: mixin ContainerSync, public List { };

output of method SyncList::add > "lock add unlock"

The example shows a class List and mixin class ContainerSync that can be applied to any class using the mixin keyword. In the example, ContainerSync is intended for synchronizing access to container classes that provide a method add. Applying the mixin to class List is done by defining subclass SyncList and using the mixin keyword. Using C++, we would implement the code of the mixin directly into class SyncList and thus could not reuse it for synchronizing different container classes. As for class refinements of FOP, mixins can introduce members and extend methods. In the example above, method add is overridden by the mixin to introduce synchronization code (illustrated using the "lock" and "unlock" output). The super keyword is used to call the overridden method.

Mixins vs. FOP. While FOP allows for composing arbitrary features that crosscut multiple classes, it does not allow to compose multiple variants of a class that can be used at the same time. For example, a list product line that provides different variants of linked lists, e.g., synchronized and sorted lists, can be implemented with a class List that that is extended in features Sync and Sort. Synchronized and sorted lists as well as synchronized-sorted lists can be built by composing the according features. However, when a programmer needs a synchronized list and a sorted list at the same time she has to create all required variants of the list product line. Mixins avoid this additional composition process and allow for composing different variants of a class in the source code. This is often much simpler and does not require to create a dedicated List product line. Hence, mixins are a composition mechanism that allow to compose single classes (usually within the source code) while FOP provides large scale composition of multiple classes at the same time.

FeatureC++ Mixins vs. C++ Multiple Inheritance. Mixins are a generalization of inheritance and also provide an alternative to multiple inheritance [1]. For example, we can use plain C++ to build a synchronized and a sorted list by creating two subclasses of List. A synchronized-sorted-list could then be created by inherting from both classes which results in the diamond problem which causes a duplication of the superclass List. In C++ this is solved using using virtual inheritance. With mixins, the synchronized and the sorted part of the list can be created as separate mixin classes (as shown in the example above) and can be composed with the basic List class as required. This scales for an arbitrary number of mixins and even allows to apply the mixins to other classes. In contrast to multiple inheritance, it allows for calling overridden methods to successively extend their functionality. For example, method add in our List class can be extended to implement sorting and synchronization and the original method can be called using the super keyword. Implementing this with C++ requires to explicitely call the method of the sibling class which requires to know that class in advance.

FeatureC++ Mixins vs. C++ Templates. At this point we want to mention that mixins can also be implemented with C++ templates. This, however, means to add a template argument to the mixin class for the super class which heavily complicates the source code, especially when mixins for generic classes (e.g., a generic List) are created. For example, if we add template arguments to the List class shown above in order to provide a generic element type, this is quite simple when using FeatureC++ mixins. Using C++ templates, means that we now have to deal with two template arguments in the mixin, one for the element type of the list class and one for the super class of the mixin. Furthermore, it can be very complicated to implement C++ templates because for template instantiation, all required template code has to be included to be known to the compiler. This often causes problems when separating implementation and header (as usual in C++) for a template. With FeatureC++ mixins this problem does not occur.

Feature-oriented Programmin with Mixins. When and how to use mixins in FOP code. Coming soon...

References

[1] Gilad Bracha and William Cook. Mixin-based Inheritance