Monday, October 6, 2014

How to Implement Policy Classes in C++

Policy-based class design is a powerful technique described in Modern C++: Generic Programming and Design Patterns Applied book. It's similar to a strategy design pattern, but with all the type-safety thanks to the use of C++ templates.

Below is a trivial example how to design a library with policy classes.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <iostream>
#include <string>
using namespace std;
 
template<class T>
struct HelloPolicy {
    static void saySomething(const T& t) {
        cout << "Hello World, " << t.getName() << endl;
    }
};
 
template<class T>
struct ByePolicy {
    static void saySomething(const T& t) {
        cout << "Bye World, " << t.getName() << endl;
    }
};
 
struct Foo {
    string getName() const {
        return "Foo";
    }
};
 
struct Bar {
    string getName() const {
        return "Bar";
    }
};
 
template<template <class> class Policy>
class FooPolicy : public Policy<Foo> {
public:
    void doSomething() {
        Foo foo;
        Policy<Foo>().saySomething(foo);
    }
};
 
template<template <class> class Policy>
class BarPolicy : public Policy<Bar> {
public:
    void doSomething() {
        Bar bar;
        Policy<Bar>().saySomething(bar);
    }
};
 
int main() {
    FooPolicy<HelloPolicy> f1;
    f1.doSomething();
 
    FooPolicy<ByePolicy> f2;
    f2.doSomething();
 
    BarPolicy<HelloPolicy> b1;
    b1.doSomething();
 
    BarPolicy<ByePolicy> b2;
    b2.doSomething();
     
    return 0;
 }
Output:
Hello World, Foo
Bye World, Foo
Hello World, Bar
Bye World, Bar