Шаблон посетителя из базового класса

Я пытаюсь реализовать шаблон посетителя в С++ https://en.wikipedia.org/wiki/Visitor_pattern< /а>

Как я могу использовать этот шаблон при работе с объектами в качестве их базового класса? Я хочу, чтобы посетитель мог анализировать иерархию классов. В моем конкретном случае, а не в том примере, который я привожу, я хочу разобрать массив объектов в список json, где каждый объект имеет как члены родительского класса, так и определенные члены подкласса. Разве шаблон посетителя здесь не правильный подход?

#include <iostream>
#include <vector>

class Animal;
class Dog;
class Cat;

class Visitor {
public:
    virtual void visit(Animal *a) = 0;
    virtual void visit(Dog *d) = 0;
    virtual void visit(Cat *c) = 0;
};

struct Animal {
    void accept(Visitor &v) { v.visit(this); }
    int a;
protected:
     Animal(int an) : a(an) {}
};

struct Dog : Animal {
    Dog(int dn, int an) : Animal(an), d(dn) {}
    void accept(Visitor &v) { v.visit(this); }
    int d;
};

struct Cat : Animal {
    Cat(int cn, int an) : Animal(an), c(cn) {}
    void accept(Visitor &v) { v.visit(this); }
    int c;
};

struct ConcreteVisitor : Visitor {
    void visit(Animal *a) { 
        std::cout << "Animal<" << a->a << ">"; 
    }

    void visit(Dog *d) {
        std::cout << "Dog<" << d->d << ", "; 
        visit((Animal *)d); 
        std::cout << ">" << std::endl;
    }

    void visit(Cat *c) {
        std::cout << "Cat<" << c->c << ", "; 
        visit((Animal *)c); 
        std::cout << ">" << std::endl;
    }
};

int main() {
    std::vector<Animal *> animals;
    animals.push_back(new Dog(4, 5));
    animals.push_back(new Cat(6, 7));

    ConcreteVisitor v;
    for (Animal *a : animals) {
         a->accept(v);
     }
}

Это печатает Animal<5> Animal<7>


person shane    schedule 17.05.2017    source источник
comment
Шаблоны здесь не нужны, вместо этого вы должны узнать о virtual функциях-членах.   -  person Some programmer dude    schedule 17.05.2017
comment
@Someprogrammerdude Я отредактировал код, чтобы вместо этого использовать виртуальный, но это все равно не решает мою проблему.   -  person shane    schedule 17.05.2017


Ответы (1)


Вы также должны сделать accept виртуальным.

person DAle    schedule 17.05.2017
comment
да, это сделал это - person shane; 17.05.2017