#include <iostream>
using namespace std;
class Base {
public:
virtual ~Base() {}
virtual void func1() {}
virtual void func2() {}
virtual void func3() {}
};
template<class B> class Derived1 : public B {
public:
virtual void func1() {
cout << "Derived1" << endl;
}
};
template<class B> class Derived2 : public B {
public:
virtual void func2() {
cout << "Derived2" << endl;
}
};
template<class B> class Derived3 : public B {
public:
virtual void func3() {
cout << "Derived3" << endl;
}
};
typedef Derived1<Derived2<Base> > Foo;
typedef Derived2<Derived3<Base> > Qoo;
typedef Derived1<Derived1<Base> > Hoo;
int main() {
Base *foo = new Foo;
foo->func1();
foo->func2();
foo->func3(); // do nothing
cout << "---------" << endl;
Base *qoo = new Qoo;
qoo->func1(); // do nothing
qoo->func2();
qoo->func3();
cout << "---------" << endl;
Base *hoo = new Hoo;
hoo->func1(); // output once
}
I2luY2x1ZGUgPGlvc3RyZWFtPgogCnVzaW5nIG5hbWVzcGFjZSBzdGQ7CiAKY2xhc3MgQmFzZSB7CnB1YmxpYzoKICAgIHZpcnR1YWwgfkJhc2UoKSB7fQogICAgdmlydHVhbCB2b2lkIGZ1bmMxKCkge30KICAgIHZpcnR1YWwgdm9pZCBmdW5jMigpIHt9CiAgICB2aXJ0dWFsIHZvaWQgZnVuYzMoKSB7fQoKfTsKIAp0ZW1wbGF0ZTxjbGFzcyBCPiBjbGFzcyBEZXJpdmVkMSA6IHB1YmxpYyBCIHsKcHVibGljOgogICAgdmlydHVhbCB2b2lkIGZ1bmMxKCkgewogICAgICAgIGNvdXQgPDwgIkRlcml2ZWQxIiA8PCBlbmRsOwogICAgfQp9OwogCnRlbXBsYXRlPGNsYXNzIEI+IGNsYXNzIERlcml2ZWQyIDogcHVibGljIEIgewpwdWJsaWM6CiAgICB2aXJ0dWFsIHZvaWQgZnVuYzIoKSB7CiAgICAgICAgY291dCA8PCAiRGVyaXZlZDIiIDw8IGVuZGw7CiAgICB9Cn07CiAKdGVtcGxhdGU8Y2xhc3MgQj4gY2xhc3MgRGVyaXZlZDMgOiBwdWJsaWMgQiB7CnB1YmxpYzoKICAgIHZpcnR1YWwgdm9pZCBmdW5jMygpIHsKICAgICAgICBjb3V0IDw8ICJEZXJpdmVkMyIgPDwgZW5kbDsKICAgIH0KfTsKCnR5cGVkZWYgRGVyaXZlZDE8RGVyaXZlZDI8QmFzZT4gPiBGb287CnR5cGVkZWYgRGVyaXZlZDI8RGVyaXZlZDM8QmFzZT4gPiBRb287CnR5cGVkZWYgRGVyaXZlZDE8RGVyaXZlZDE8QmFzZT4gPiBIb287CgppbnQgbWFpbigpIHsKCiAgICBCYXNlICpmb28gPSBuZXcgRm9vOwogICAgZm9vLT5mdW5jMSgpOwogICAgZm9vLT5mdW5jMigpOwogICAgZm9vLT5mdW5jMygpOyAgLy8gZG8gbm90aGluZwogICAgY291dCA8PCAiLS0tLS0tLS0tIiA8PCBlbmRsOwogICAgCiAgICBCYXNlICpxb28gPSBuZXcgUW9vOwogICAgcW9vLT5mdW5jMSgpOyAgLy8gZG8gbm90aGluZwogICAgcW9vLT5mdW5jMigpOwogICAgcW9vLT5mdW5jMygpOwogICAgY291dCA8PCAiLS0tLS0tLS0tIiA8PCBlbmRsOwogICAgCiAgICBCYXNlICpob28gPSBuZXcgSG9vOwogICAgaG9vLT5mdW5jMSgpOyAgLy8gb3V0cHV0IG9uY2UKfQ==