J
Jon Øyvind Kjellman
Hi, suppose you have the following classes:
#include <iostream>
class Foo {
public:
virtual void foo() { std::cout << "Foo::foo()\n"; }
virtual ~Foo() {}
};
class Bar {
public:
virtual void bar() { std::cout << "Bar::bar()\n"; }
virtual ~Bar() {}
};
class FooBar : public Foo, public Bar {
public:
void foo() { std::cout << "FooBar::Foo()\n"; }
void bar() { std::cout << "FooBar::Bar()\n"; }
};
template<typename T>
class Wrapper {
T obj;
public:
T& get_obj() { return obj; }
Wrapper(T obj) : obj(obj) { }
~Wrapper() { }
};
Now suppose you would like to use a Wrapper<FooBar*> object, but for it to also be castable to both Wrapper<Foo*> and Wrapper<Bar*> so that you could do something along the lines of the following snippet.
void call_wrapped_foo(Wrapper<Foo*>& wrapped_foo)
{
wrapped_foo.get_obj()->foo();
}
void call_wrapped_bar(Wrapper<Bar*>& wrapped_bar)
{
wrapped_bar.get_obj()->bar();
}
int main(int argc, char** argv)
{
FooBar foobar;
Wrapper<FooBar*> wrapped_foobar(&foobar);
// Illegal!!
call_wrapped_foo(dynamic_cast<Wrapper<Foo*> >(wrapped_foobar));
call_wrapped_bar(dynamic_cast<Wrapper<Bar*> >(wrapped_foobar));
}
As expected the two last lines will not compile. However, can anyone suggest a pattern of some sorts that will allow me to do something similar (not necessarily dynamic_cast) without changing Foo, Bar or FooBar. Wrapper does not necessarily need to be a template and other helper classes may be added. I have thought about different pattern's involving virtual inheritance, but couldn't find something that will work. Short and elegant earns bonus points
Regards,
Jon Øyvind Kjellman
#include <iostream>
class Foo {
public:
virtual void foo() { std::cout << "Foo::foo()\n"; }
virtual ~Foo() {}
};
class Bar {
public:
virtual void bar() { std::cout << "Bar::bar()\n"; }
virtual ~Bar() {}
};
class FooBar : public Foo, public Bar {
public:
void foo() { std::cout << "FooBar::Foo()\n"; }
void bar() { std::cout << "FooBar::Bar()\n"; }
};
template<typename T>
class Wrapper {
T obj;
public:
T& get_obj() { return obj; }
Wrapper(T obj) : obj(obj) { }
~Wrapper() { }
};
Now suppose you would like to use a Wrapper<FooBar*> object, but for it to also be castable to both Wrapper<Foo*> and Wrapper<Bar*> so that you could do something along the lines of the following snippet.
void call_wrapped_foo(Wrapper<Foo*>& wrapped_foo)
{
wrapped_foo.get_obj()->foo();
}
void call_wrapped_bar(Wrapper<Bar*>& wrapped_bar)
{
wrapped_bar.get_obj()->bar();
}
int main(int argc, char** argv)
{
FooBar foobar;
Wrapper<FooBar*> wrapped_foobar(&foobar);
// Illegal!!
call_wrapped_foo(dynamic_cast<Wrapper<Foo*> >(wrapped_foobar));
call_wrapped_bar(dynamic_cast<Wrapper<Bar*> >(wrapped_foobar));
}
As expected the two last lines will not compile. However, can anyone suggest a pattern of some sorts that will allow me to do something similar (not necessarily dynamic_cast) without changing Foo, Bar or FooBar. Wrapper does not necessarily need to be a template and other helper classes may be added. I have thought about different pattern's involving virtual inheritance, but couldn't find something that will work. Short and elegant earns bonus points
Regards,
Jon Øyvind Kjellman