Runtime polymorphism for two different classes - c++

I have two classes B andY which I cannot change or edit by requirement. They have functions doing the same thing but with different names.
I want to a have a common interfaces with selecting the class at run time depending on the some input variable as described in the code below. I am not sure which design pattern should I use. How to create WrapperYB class which selects Y::show or B::showing depending on the object created.
class A
{
public:
A() {}
virtual ~A();
virtual void show() { cout << "show A" << endl;}
};
class B:A
{
public:
B() {}
virtual ~B();
virtual void show() { cout << "show B" << endl;}
};
class X
{
char m_i;
public:
Y() { m_i = 'X';}
virtual void showing() { cout << "showing " << m_i << endl;}
};
class Y:X
{
public:
Y() { m_i = 'Y';}
virtual void showing() { cout << "showing " << m_i << endl;}
};
class WrapperYB
{
// to be implemented
public:
explicit WrapperYB(const int& type);
void show();
};
int main(){
WrapperYB objY(1);
objY.show(); // must call Y::showing
WrapperYB objB(0);
objB.show(); // must call B::show
}

If your compiler supports the C++17 Standard, you could try this solution using std::variant. This is a similar idea to the solution in #Nicolas's answer, but variant will take care of the implementation details for you, won't use dynamic memory allocation, and has support for additional things like copy and assignment.
#include <variant>
#include <utility>
#include <type_traits>
class WrapperYB {
public:
using variant_type = std::variant<Y, B>;
template <typename... Args,
std::enable_if_t<std::is_constructible_v<variant_type, Args...>>* = nullptr>
WrapperYB(Args&& ... args) : m_variant(std::forward<Args>(args)...) {}
variant_type& variant() noexcept { return m_variant; }
const variant_type& variant() const noexcept { return m_variant; }
void show()
{ std::visit(ShowImpl{}, m_variant); }
private:
struct ShowImpl {
void operator() (Y& y) const { y.showing(); }
void operator() (B& b) const { b.show(); }
};
variant_type m_variant;
};
See the full working example on coliru.
You might generalize the wrapper by letting it contain a std::unique_ptr<A> or std::unique_ptr<X> instead.

I'm proposing this:
#include <iostream>
using namespace std;
class A
{
public:
A() {}
virtual ~A() {}
virtual void show() { cout << "show A" << endl;}
};
class B:A
{
public:
B() {}
virtual ~B() {}
virtual void show() { cout << "show B" << endl;}
};
class X
{
protected:
char m_i;
public:
X () { m_i = 'X';}
virtual void showing() { cout << "showing " << m_i << endl;}
};
class Y:X
{
public:
Y() { m_i = 'Y';}
virtual void showing() { cout << "showing " << m_i << endl;}
};
class WrapperYB
{
public:
enum class Which { B, Y };
public:
explicit WrapperYB (int n)
: which(Which(n))
{
switch (which)
{
case Which::B: ptr.b = new B; break;
case Which::Y: ptr.y = new Y; break;
}
}
~WrapperYB ()
{
switch (which)
{
case Which::B: delete ptr.b; break;
case Which::Y: delete ptr.y; break;
}
}
WrapperYB (const WrapperYB&) = delete;
WrapperYB& operator = (const WrapperYB&) = delete;
public:
void show()
{
switch (which)
{
case Which::B: ptr.b->show() ; break;
case Which::Y: ptr.y->showing(); break;
}
}
private:
Which which;
union {
Y* y;
B* b;
} ptr;
};
int main(){
WrapperYB objY(1);
objY.show(); // must call Y::showing
WrapperYB objB(0);
objB.show(); // must call B::show
}
It's not a "Vanilla" design pattern, I don't think, and more of combination of adapter and discriminated union.
Note that WrapperYB cannot be copied or assigned, as is.

You can use a standard virtual dispatch method with an abstract base adaptor class and subclasses for each object type needed. Create the object with a factory method.
#include <memory>
//pre-defined structures Y, B
struct Y
{
Y(){}
~Y(){}
void show(){}
};
struct B
{
B(){}
~B(){}
void showing(){}
};
// Abstract adaptor base class.
struct Adaptor
{
virtual void show() = 0;
};
// A subclass of Adaptor for each type of object to be wrapped.
struct Adaptor_Y: Adaptor
{
Adaptor_Y(): y(){}
void show() override
{
y.show();
}
private:
Y y;
};
struct Adaptor_B: Adaptor
{
Adaptor_B(): b(){}
void show() override
{
b.showing();
}
private:
B b;
};
// Factory method constructs the proper object and returns a pointer.
std::unique_ptr<Adaptor> get_adaptor(int flag)
{
if(flag == 0)
{
return std::make_unique<Adaptor_B>();
}
else if(flag == 1)
{
return std::make_unique<Adaptor_Y>();
}
else throw std::runtime_error("Invalid flag value");
}

Related

Virtual template function in c++

I have been looking for a way to use both templating and polymorphism at the same time. Here's a simplified version of my problem:
#include <iostream>
#include <vector>
using std::cout;
using std::endl;
//*******************************************************************
//*******************************************************************
struct DerivedStuff1
{
static void eval() { cout << "evaluating DerivedStuff1" << endl; }
};
struct DerivedStuff2
{
static void eval() { cout << "evaluating DerivedStuff2" << endl; }
};
//*******************************************************************
//*******************************************************************
class BaseClass
{
public:
template<typename StuffType> virtual void eval() const = 0;
};
class DerivedClass1 : public BaseClass
{
public:
template<typename StuffType> virtual void eval() const
{
std::cout << "We are in DerivedClass1: ";
StuffType::eval();
}
};
class DerivedClass2 : public BaseClass
{
public:
template<typename StuffType> virtual void eval() const
{
std::cout << "We are in DerivedClass2: ";
StuffType::eval();
}
};
int main()
{
BaseClass* c1 = new DerivedClass1;
c1->eval<DerivedStuff1>();
c1->eval<DerivedStuff2>();
BaseClass* c2 = new DerivedClass2;
c2->eval<DerivedStuff1>();
c2->eval<DerivedStuff2>();
return 0;
}
This code does not compile because virtual template functions are not allowed in C++. I found a few approaches to tackle this problem (CRTP, etc.) but none of them were really satisfying. Is there no elegant way to get around that issue?
The visitor pattern turns run-time polymorphism on its side and makes runtime-polymorphic function templates possible. It has other legitimate uses apart from templatisation, so I guess you can call it somewhat elegant.
Your example can look as follows:
#include <iostream>
class DerivedStuff1 {
public:
static void eval() { std::cout << "Evaluating DerivedStuff1\n"; }
};
class DerivedStuff2 {
public:
static void eval() { std::cout << "Evaluating DerivedStuff2\n"; }
};
class DerivedClass1; class DerivedClass2;
class BaseClassVisitor {
public:
virtual void visit(DerivedClass1&) = 0;
virtual void visit(DerivedClass2&) = 0;
};
class BaseClass {
public:
virtual void accept(BaseClassVisitor& v) = 0;
};
class DerivedClass1 : public BaseClass
{
public:
virtual void accept(BaseClassVisitor& v) { v.visit(*this); }
};
class DerivedClass2 : public BaseClass
{
public:
virtual void accept(BaseClassVisitor& v) { v.visit(*this); }
};
template <typename StuffType>
class EvalVisitor : public BaseClassVisitor
{
virtual void visit(DerivedClass1&) {
std::cout << "We are in DerivedClass1: ";
StuffType::eval();
}
virtual void visit(DerivedClass2&) {
std::cout << "We are in DerivedClass2: ";
StuffType::eval();
}
};
int main()
{
EvalVisitor<DerivedStuff1> e1;
EvalVisitor<DerivedStuff2> e2;
BaseClass* c1 = new DerivedClass1;
c1->accept(e1);
c1->accept(e2);
BaseClass* c2 = new DerivedClass2;
c2->accept(e1);
c2->accept(e2);
return 0;
}
Demo
Of course all shortcomings of Visitor apply here.
You could reinvent the vtable and resolve the function pointer at run time. You will, however, have to explicitely instantiate the template on the derived class, but I don't see any approach to this that won't require that.
Quick and dirty example:
#include <map>
#include <iostream>
class Base {
public:
typedef void (Base::*eval_ptr)();
using eval_vtable = std::map<std::type_index, eval_ptr>;
Base(eval_vtable const& eval_p) : eval_ptrs(eval_p) {}
template<typename T>
void eval() {
auto handler = eval_ptrs.find(type_index(typeid(T)));
if(handler != eval_ptrs.end()) {
auto handler_ptr = handler->second;
(this->*handler_ptr)();
}
}
eval_vtable const& eval_ptrs;
};
class Derived : public Base {
public:
Derived()
: Base(eval_functions) {}
template<typename T>
void eval_impl() {
std::cout << typeid(T).name() << "\n";
}
static eval_vtable eval_functions;
};
Base::eval_vtable Derived::eval_functions = {
{ type_index(typeid(int)), eval_ptr(&Derived::eval_impl<int>) },
{ type_index(typeid(float)), eval_ptr(&Derived::eval_impl<float>) },
{ type_index(typeid(short)), eval_ptr(&Derived::eval_impl<short>) },
};
int main(int argc, const char* argv[]) {
Derived x;
Base * x_as_base = &x;
x_as_base->eval<int>(); // calls Derived::eval_impl<int>()
return 0;
}
This won't be exactly fast, but it will give you the closest thing to templated virtual functions that I can think of.
Edit: For the record I don't advocate anyone use this. I would much rather revisit the design to avoid being painted in this particular corner in the first place. Please consider my answer as an academic solution to a theoretical problem, not an actual engineering recommendation.
Since virtual template methods in C++ arent allowed, you can make a class template and call static function of class template param.
#include <iostream>
#include <vector>
using std::cout;
using std::endl;
//*******************************************************************
//*******************************************************************
struct DerivedStuff1
{
static void eval() { cout << "evaluating DerivedStuff1" << endl; }
};
struct DerivedStuff2
{
static void eval() { cout << "evaluating DerivedStuff2" << endl; }
};
//*******************************************************************
//*******************************************************************
class BaseClass
{
public:
virtual void eval() const = 0;
};
template<typename StuffType>
class DerivedClass1 : public BaseClass
{
public:
virtual void eval() const
{
std::cout << "We are in DerivedClass1: ";
StuffType::eval();
}
};
template<typename StuffType>
class DerivedClass2 : public BaseClass
{
public:
virtual void eval() const
{
std::cout << "We are in DerivedClass2: ";
StuffType::eval();
}
};
int main()
{
BaseClass* c1 = new DerivedClass1<DerivedStuff1>;
c1->eval();
c1 = new DerivedClass1<DerivedStuff2>;
c1->eval();
BaseClass* c2 = new DerivedClass2<DerivedStuff1>;
c2->eval();
c2 = new DerivedClass2<DerivedStuff2>;
c2->eval();
// deletes
return 0;
}
Output
We are in DerivedClass1: evaluating DerivedStuff1
We are in DerivedClass1: evaluating DerivedStuff2
We are in DerivedClass2: evaluating DerivedStuff1
We are in DerivedClass2: evaluating DerivedStuff2
You cannot mix templates (compile time) and polymorphic (runtime). That's it.
So, a posible workaround is remove templates. For example, it could take a function pointer or just more polymorphism:
//*******************************************************************
//*******************************************************************
struct InterfaceStuff{
virtual void eval() = 0;
}
struct DerivedStuff1 : public InterfaceStuff
{
void eval() { cout << "evaluating DerivedStuff1" << endl; }
};
struct DerivedStuff2 : public InterfaceStuff
{
void eval() { cout << "evaluating DerivedStuff2" << endl; }
};
//*******************************************************************
//*******************************************************************
class BaseClass
{
public:
virtual void eval(InterfaceStuff* interface) const = 0;
};
class DerivedClass1 : public BaseClass
{
public:
virtual void eval(InterfaceStuff* interface) const
{
std::cout << "We are in DerivedClass1: ";
interface->eval();
}
};
class DerivedClass2 : public BaseClass
{
public:
virtual void eval(InterfaceStuff* interface) const
{
std::cout << "We are in DerivedClass2: ";
interface->eval();
}
};
Another posible workaround is remove polymorphism, just use more templates:
struct DerivedStuff1
{
static void eval() { cout << "evaluating DerivedStuff1" << endl; }
};
struct DerivedStuff2
{
static void eval() { cout << "evaluating DerivedStuff2" << endl; }
};
//*******************************************************************
//*******************************************************************
class BaseClass
{
public:
template<typename Eval,typename StuffType> void eval() const
{
Eval::eval();
StuffType::eval();
}
};
class DerivedClass1 : public BaseClass
{
};
class DerivedClass2 : public BaseClass
{
};
One way of another, you have to choose one.

Automatic method selection based on class instance

I have two variants of the same method. I also have an instance of a base class type, but I don't know what specific class it is an instance of. I now want to automatically select the appropriate method depending on the actual type of the object. It seems impossible though and the only solution I can come up with is to check all possibilities by casting.
There has to be a nicer solution though.
Here is my minimal example:
// Example program
#include <iostream>
#include <string>
#include <memory>
class A
{
public:
virtual void bar() const = 0;
};
class B : public A
{
public:
void bar() const
{
std::cout << "B.bar()" << std::endl;
}
};
class C : public A
{
public:
void bar() const
{
std::cout << "C.bar()" << std::endl;
}
};
class Z
{
public:
Z(int variable) : m_variable(variable) {};
void foo(std::shared_ptr<B> b)
{
std::cout << "Calling foo(B) method! " << m_variable << std::endl;
b->bar();
}
void foo(std::shared_ptr<C> c)
{
std::cout << "Calling foo(C) method!" << m_variable << std::endl;
c->bar();
}
private:
int m_variable;
};
int main()
{
std::shared_ptr<A> b(new B());
Z z(42);
//z.foo(b); // This doesn't work
// But this does
std::shared_ptr<B> b_cast = std::dynamic_pointer_cast<B>(b);
if (b_cast.get())
z.foo(b_cast);
}
http://cpp.sh/9fqne
At the moment I have to resort to dynamic_pointer_cast, but I find it kinda ugly and not very maintainable.
I also don't want to add the functionality of foo() to the classes B and C, because those are small independent data structures on which many other classes operate.
Thank you very much!
EDIT: In the original post I simplified a bit too much. The new example should clear things up.
Add a pure virtual function foo() to your base class and override in subsequent derived classes. Then have your global function foo() (which has nothing to do with member functions with the same name) accept a reference to std::shared_ptr const as a parameter:
#include <iostream>
#include <memory>
class A{
public:
virtual void foo() = 0;
};
class B : public A{
public:
void foo() override{
std::cout << "Calling foo(B) method!" << std::endl;
}
};
class C : public A{
public:
void foo() override{
std::cout << "Calling foo(C) method!" << std::endl;
}
};
void foo(const std::shared_ptr<A>& param){
param->foo();
}
int main(){
std::shared_ptr<A> b = std::make_shared<B>();
std::shared_ptr<A> c = std::make_shared<C>();
foo(b);
foo(c);
}
As BoBTFish pointed out, the visitor pattern is a potential solution for this problem:
// Example program
#include <iostream>
#include <string>
#include <memory>
class B;
class C;
class Visitor
{
public:
virtual void visit(B* b) const = 0;
virtual void visit(C* b) const = 0;
};
class A
{
public:
virtual void bar() const = 0;
virtual void accept(const Visitor* visitor) = 0;
};
class B : public A
{
public:
void bar() const
{
std::cout << "B.bar()" << std::endl;
}
void accept(const Visitor* visitor)
{
visitor->visit(this);
}
};
class C : public A
{
public:
void bar() const
{
std::cout << "C.bar()" << std::endl;
}
void accept(const Visitor* visitor)
{
visitor->visit(this);
}
};
class Z : public Visitor
{
public:
Z(int variable) : m_variable(variable) {};
void visit(B* b) const
{
std::cout << "Calling foo(B) method! " << m_variable << std::endl;
b->bar();
}
void visit(C* c) const
{
std::cout << "Calling foo(C) method!" << m_variable << std::endl;
c->bar();
}
private:
int m_variable;
};
int main()
{
std::shared_ptr<A> b(new B());
Z z(42);
b->accept(&z);
}
http://cpp.sh/2vah5
Thank you very much!

Dynamically call a function by overriding the typecast

#include <iostream>
using namespace std;
class Base
{
public:
void who()
{
cout << "I am " << _name << endl;
}
protected:
std::string _name;
};
class A : public Base
{
public:
A()
{
_name = "A class";
}
};
class B : public Base
{
public:
B()
{
_name = "B class";
}
};
class Wrapper
{
public:
Wrapper(Base *i):_data(i)
{
}
operator A()
{
A a;
// dynamic_cast<A*>(_data);
return a;
}
operator B()
{
B a;
// dynamic_cast<B*>(_data);
return a;
}
private:
Base* _data;
};
void madeForClass(A iObject)
{
cout << "call madeForClass A";
}
void madeForClass(B iObject)
{
cout << "call madeForClass B";
}
int main()
{
A a;
Base* b = &a;
madeForClass(Wrapper(b));
return 0;
}
when I execute this, I get error from compile saying:
error: call of overloaded 'madeForClass(Wrapper)' is ambiguous
I understand that it cannot deduce right function even though i have overloaded the typecast. But, How can I achieve such dynamism?
For more info, I somehow want to use the dynamic_cast in the overloading function or somewhere in such a way that based on the outcome of cast it should choose the corresponding madeForClass function.
For the given example, the cast will fail for 'B' hence should call madeForClass(A i);
As alternative, you may do
class Wrapper
{
public:
Wrapper(Base *i) : _data(i) {}
template <typename F>
auto Apply(F f)
{
if (auto a = dynamic_cast<A*>(_data)) {
f(*a);
} else if (auto b = dynamic_cast<B*>(_data)){
f(*b);
}
}
private:
Base* _data;
};
And then
Wrapper(base).Apply([](const auto& e){ madeForClass(e); });
Demo
or use Visitor instead of manual dynamic_cast

Strategy for calling functions in classes with diamond inheritance and virtual base classes

If we have diamond inheritance and use public virtual base classes, we can stop the first constructor from being called multiple times. Now, I'd like to do the same sort of thing for functions outside of the constructor. For example, the code:
#include <iostream>
struct A {
virtual void foo() {
std::cout << "A" << std::endl;
}
};
struct B : virtual public A {
virtual void foo() {
A::foo();
std::cout << "B" << std::endl;
}
};
struct C : virtual public A {
virtual void foo() {
A::foo();
std::cout << "C" << std::endl;
}
};
struct D : public B, public C{
virtual void foo() {
B::foo();
C::foo();
std::cout << "D" << std::endl;
}
};
int main() {
D d;
d.foo();
}
produces the result
A
B
A
C
D
I'd like to modify it so that it just produces
A
B
C
D
What sort of strategies or patterns accomplish this?
EDIT 1
I like Tony D's answer better than the following. Nonetheless, it's in theory possible to use constructors of another class in order to define the proper hierarchy of functions. Specifically
#include <iostream>
struct A;
struct B;
struct C;
struct D;
namespace foo {
struct A {
A(::A* self);
};
struct B : virtual public A {
B(::B* self);
};
struct C : virtual public A {
C(::C* self);
};
struct D : public B, public C{
D(::D* self);
};
}
struct A {
private:
friend class foo::A;
friend class foo::B;
friend class foo::C;
friend class foo::D;
int data;
public:
A() : data(0) {}
virtual void foo() {
(foo::A(this));
}
void printme() {
std::cout << data << std::endl;
}
};
struct B : virtual public A {
virtual void foo() {
(foo::B(this));
}
};
struct C : virtual public A {
virtual void foo() {
(foo::C(this));
}
};
struct D : public B, public C{
virtual void foo() {
(foo::D(this));
}
};
foo::A::A(::A* self) {
self->data+=1;
std::cout << "A" << std::endl;
}
foo::B::B(::B* self) : A(self) {
self->data+=2;
std::cout << "B" << std::endl;
}
foo::C::C(::C* self) : A(self) {
self->data+=4;
std::cout << "C" << std::endl;
}
foo::D::D(::D* self) : A(self), B(self), C(self) {
self->data+=8;
std::cout << "D" << std::endl;
}
int main() {
D d;
d.foo();
d.printme();
}
Basically, the classes inside of the namespace foo do the computation for the function named foo. This seems a little verbose, so perhaps there's a better way to do it.
EDIT 2
Thanks again to Tony D for clarifying the above example. Yes, essentially what the above does is create temporary variables that adhere to the virtual base designation. In this way, we can use the constructor in order to prevent redundant computations. The extra cruft was to try and show how to get access to access to private members that may have been buried in the base class. Thinking about it a little bit more, there's another way to do this, which may or may not be cleaner depending on the application. I'll leave it here for reference. As with the last example, the weakness is that we're essentially required to wire the the inheritance again, by hand.
#include <iostream>
struct A {
protected:
int data;
public:
A() : data(0) {}
struct foo{
foo(A & self) {
self.data+=1;
std::cout << "A" << std::endl;
}
};
void printme() {
std::cout << data << std::endl;
}
};
struct B : virtual public A {
struct foo : virtual public A::foo {
foo(B & self) : A::foo(self) {
self.data+=2;
std::cout << "B" << std::endl;
}
};
};
struct C : virtual public A {
struct foo : virtual public A::foo {
foo(C & self) : A::foo(self) {
self.data+=4;
std::cout << "C" << std::endl;
}
};
};
struct D : public B, public C{
struct foo : public B::foo, public C::foo {
foo(D & self) : A::foo(self) , B::foo(self), C::foo(self) {
self.data+=8;
std::cout << "D" << std::endl;
}
};
};
int main() {
D d;
(D::foo(d));
d.printme();
}
Essentially, the call (D::foo(d)) creates a temporary who's constructor does the actions we desire. We pass in the object d by hand in order to access to the memory. Since the classes foo are inside of the classes A..D, this gives us access to the protected members.
Just an implementation of polkadotcadaver's idea. Here, Limiter is designed to be a reusable mechanism for this, and the virtual base class should have a member of that type. The controlled base-class function uses bool Limiter::do_next() to ask whether it should run "as usual" or return immediately, while the derived classes calling the base-class function get a scope-guard object from the limiter that takes ownership if not already claimed, and releases any ownership it had on destruction.
#include <iostream>
class Limiter
{
public:
Limiter() : state_(Unlimited) { }
class Scope
{
public:
Scope(Limiter& l)
: p_(l.state_ == Unlimited ? &l : NULL)
{ if (p_) p_->state_ = Do_Next; }
~Scope() { if (p_) p_->state_ = Unlimited; }
private:
Limiter* p_;
};
Scope get() { return Scope(*this); }
bool do_next()
{
if (state_ == Do_Next) { state_ = Suspended; return true; }
return state_ != Suspended;
}
private:
enum State { Unlimited, Do_Next, Suspended } state_;
};
struct A {
Limiter limiter_;
virtual void foo() {
if (limiter_.do_next())
std::cout << "A" << std::endl;
}
};
struct B : virtual public A {
virtual void foo() {
Limiter::Scope ls = A::limiter_.get();
A::foo();
std::cout << "B" << std::endl;
}
};
struct C : virtual public A {
virtual void foo() {
Limiter::Scope ls = A::limiter_.get();
A::foo();
std::cout << "C" << std::endl;
}
};
struct D : public B, public C{
virtual void foo() {
Limiter::Scope ls = A::limiter_.get();
B::foo();
C::foo();
std::cout << "D" << std::endl;
}
};
int main() {
D d;
d.foo();
}
Discussion of technique edited into your question
Took me a while to work out what you were doing in your code ;-P - so for the sake of discussion I'll post what I boiled it down to:
#include <iostream>
namespace foo {
struct A {
A() { std::cout << "A\n"; }
};
struct B : virtual public A {
B() { std::cout << "B\n"; }
};
struct C : virtual public A {
C() { std::cout << "C\n"; }
};
struct D : public B, public C{
D() { std::cout << "D\n"; }
};
}
struct A { virtual void foo() { foo::A(); } };
struct B : virtual public A { void foo() { foo::B(); } };
struct C : virtual public A { void foo() { foo::C(); } };
struct D : public B, public C { void foo() { foo::D(); } };
int main() {
D d;
d.foo();
}
For others' sake - this works by having the A..D::foo() functions create temporary objects of types foo::A..D, the constructors for which honour the virtual base designation so foo::A::A() is only called once.
As a general solution, an issue with this is that you have to manually synchronise the foo:: structures, so there's redundancy and fragility. It's clever though!

Virtual visitor

I have a hierarchy of classes (Base and daugthers A, B, C and so on). The hierarchy tree is not finite. It’s possible to visit a Base* using the well-known visitor pattern in order to dynamically adapt to the dynamic type of Base*. The visitor has a type, like BaseVisitor. Like this:
struct BaseVisitor;
struct Base {
virtual void accept(BaseVisitor &v) = 0;
};
struct A : Base {
int a;
A(int x) : a(x) {}
~A(void) = default;
void accept(BaseVisitor &v) override {
v->visit(*this);
}
};
struct B : Base {
float b;
B(void) : b(314.f) {}
~B(void) = default;
void accept(BaseVisitor &v) override {
v->visit(*this);
}
};
struct BaseVisitor {
void visit(Base &) {}
void visit(A &a) {
std::cout << "just visited a A; a=" << a.a << std::endl;
}
void visit(B &b) {
std::cout << "just visited a B; b=" << b.b << std::endl;
}
};
Now, I’d like to make BaseVisitor an abstract class in order to inherits new visitors. The issue comes when I want to define the abstract class:
struct ABaseVisitor {
virtual void visit(Base &) = 0; /* huh? */
};
Do you have any idea?