#include <iostream>
#include <string>
#include <vector>
#include <memory>
class C;
class D;
class Visitor
{
public:
virtual ~Visitor() {}
virtual void visitC( C& c ) = 0;
virtual void visitD( D& d ) = 0;
};
class B{
private: int a; int b;
public: B(const int _a, const int _b) : a(_a), b(_b){}
virtual void tell(){ std::cout << "BASE" << std::endl; }
virtual void Accept( Visitor& v ) = 0;
};
class C : public B{
std::string s;
public: C(int _a, int _b, std::string _s) : B(_a, _b), s(_s){}
void tell() override { std::cout << "CHILD C" << std::endl; }
void CFunc() {std::cout << "Can be called only from C" << std::endl;}
virtual void Accept( Visitor& v ) { v.visitC( *this ); }
};
class D : public B{
double d;
public: D(int _a, int _b, double _d) : B(_a, _b), d(_d){}
void tell() override { std::cout << "CHILD D" << std::endl; }
void DFunc() {std::cout << "Can be called only from D" << std::endl;}
virtual void Accept( Visitor& v ) { v.visitD( *this ); }
};
int main() {
std::vector<std::unique_ptr<B>> v;
v.push_back(std::make_unique<C>(1,2, "boom"));
v.push_back(std::make_unique<D>(1,2, 44.3));
class callFuncVisitor : public Visitor
{
public:
callFuncVisitor() {}
virtual void visitC( C& c )
{
c.CFunc();
}
virtual void visitD( D& d )
{
d.DFunc();
}
};
callFuncVisitor visitor;
for(auto &el: v){
el->Accept(visitor);
}
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8bWVtb3J5PgoKY2xhc3MgQzsKY2xhc3MgRDsKY2xhc3MgVmlzaXRvcgp7CglwdWJsaWM6Cgl2aXJ0dWFsIH5WaXNpdG9yKCkge30KCXZpcnR1YWwgdm9pZCB2aXNpdEMoIEMmIGMgKSA9IDA7Cgl2aXJ0dWFsIHZvaWQgdmlzaXREKCBEJiBkICkgPSAwOwp9OwoJCgpjbGFzcyBCewogICAgcHJpdmF0ZTogaW50IGE7IGludCBiOwogICAgcHVibGljOiBCKGNvbnN0IGludCBfYSwgY29uc3QgaW50IF9iKSA6IGEoX2EpLCBiKF9iKXt9CiAgICB2aXJ0dWFsIHZvaWQgdGVsbCgpeyBzdGQ6OmNvdXQgPDwgIkJBU0UiIDw8IHN0ZDo6ZW5kbDsgfQogICAgdmlydHVhbCB2b2lkIEFjY2VwdCggVmlzaXRvciYgdiApID0gMDsKfTsKCmNsYXNzIEMgOiBwdWJsaWMgQnsKICAgIHN0ZDo6c3RyaW5nIHM7CiAgICBwdWJsaWM6IEMoaW50IF9hLCBpbnQgX2IsIHN0ZDo6c3RyaW5nIF9zKSA6IEIoX2EsIF9iKSwgcyhfcyl7fQogICAgdm9pZCB0ZWxsKCkgb3ZlcnJpZGUgeyBzdGQ6OmNvdXQgPDwgIkNISUxEIEMiIDw8IHN0ZDo6ZW5kbDsgfQogICAgdm9pZCBDRnVuYygpIHtzdGQ6OmNvdXQgPDwgIkNhbiBiZSBjYWxsZWQgb25seSBmcm9tIEMiIDw8IHN0ZDo6ZW5kbDt9CiAgICB2aXJ0dWFsIHZvaWQgQWNjZXB0KCBWaXNpdG9yJiB2ICkgeyB2LnZpc2l0QyggKnRoaXMgKTsgfQp9OwoKY2xhc3MgRCA6IHB1YmxpYyBCewogICAgZG91YmxlIGQ7CiAgICBwdWJsaWM6IEQoaW50IF9hLCBpbnQgX2IsIGRvdWJsZSBfZCkgOiBCKF9hLCBfYiksIGQoX2Qpe30KICAgIHZvaWQgdGVsbCgpIG92ZXJyaWRlIHsgc3RkOjpjb3V0IDw8ICJDSElMRCBEIiA8PCBzdGQ6OmVuZGw7IH0KICAgIHZvaWQgREZ1bmMoKSB7c3RkOjpjb3V0IDw8ICJDYW4gYmUgY2FsbGVkIG9ubHkgZnJvbSBEIiA8PCBzdGQ6OmVuZGw7fQogICAgdmlydHVhbCB2b2lkIEFjY2VwdCggVmlzaXRvciYgdiApIHsgdi52aXNpdEQoICp0aGlzICk7IH0KfTsKCmludCBtYWluKCkgewogICAgc3RkOjp2ZWN0b3I8c3RkOjp1bmlxdWVfcHRyPEI+PiB2OwoKICAgIHYucHVzaF9iYWNrKHN0ZDo6bWFrZV91bmlxdWU8Qz4oMSwyLCAiYm9vbSIpKTsKICAgIHYucHVzaF9iYWNrKHN0ZDo6bWFrZV91bmlxdWU8RD4oMSwyLCA0NC4zKSk7CgoJY2xhc3MgY2FsbEZ1bmNWaXNpdG9yIDogcHVibGljIFZpc2l0b3IKCXsKCQlwdWJsaWM6CgkJY2FsbEZ1bmNWaXNpdG9yKCkge30KCQoJCXZpcnR1YWwgdm9pZCB2aXNpdEMoIEMmIGMgKQoJCXsKCQkJYy5DRnVuYygpOwoJCX0KCQl2aXJ0dWFsIHZvaWQgdmlzaXREKCBEJiBkICkKCQl7CgkJCWQuREZ1bmMoKTsKCQl9Cgl9OwoKCWNhbGxGdW5jVmlzaXRvciB2aXNpdG9yOwogICAgZm9yKGF1dG8gJmVsOiB2KXsKICAgICAgICBlbC0+QWNjZXB0KHZpc2l0b3IpOwogICAgfQogICAgcmV0dXJuIDA7Cn0=