Вы использовали стирание типа неправильно. Ваши узлы доступны с помощью Node*
, поэтому выражение *(n.Leaf[i])
возвращает тип Node
, а не NodeA
.
То, что вы делаете, напоминает шаблон посетителя, чтобы распознать, какой класс вам нужен, вы должны использовать виртуальный метод в классе Node и переопределить его в NodeA, вызывая его с диспетчером в качестве аргумента (классический посетитель) или вызывая его из диспетчера, который вы можете распознать. какой экземпляр какой.
В первом случае узел будет вызывать метод Print и передавать его *this
.
Это минимальная переделка вашего кода, но я думаю, что он требует доработки \ оптимизации. Зависит от того, что вы на самом деле делаете, может быть, vistor будет слишком излишним.
#include <string>
#include <iostream>
#include <vector>
class Node;
class NodeA;
class AbstractPrinter
{
public:
virtual std::string Print(Node &n) =0;
virtual std::string Print(NodeA &n) =0;
};
class Node
{
public:
Node()
{
}
virtual ~Node()
{
for (auto it : Leaf)
delete it;
}
Node &Add(Node *leaf)
{
Leaf.push_back(leaf);
return *this;
}
virtual std::string Print(AbstractPrinter& p)
{
return p.Print(*this);
}
std::vector<Node *> Leaf;
};
class NodeA : public Node
{
public:
NodeA() : Node()
{
}
// if not override this, it would use Node
virtual std::string Print(AbstractPrinter& p) override
{
return p.Print(*this);
}
};
class Printer : public AbstractPrinter
{
public:
Printer() = default;
std::string Print(Node &n)
{
int i = 0, k = n.Leaf.size();
std::string res = "<n>";
for (; i < k; ++i)
res += n.Leaf[i]->Print(*this);
res += "</n>";
return res;
}
std::string Print(NodeA &n)
{
int i = 0, k = n.Leaf.size();
std::string res = "<A>";
for (; i < k; ++i)
res += n.Leaf[i]->Print(*this);
res += "</A>";
return res;
}
};
int main(int argc, const char *argv[])
{
NodeA tree;
tree.Add(new NodeA).Add(new NodeA);
Printer p;
std::cout << tree.Print(p) << std::endl;
return 0;
}