【发布时间】:2016-08-07 06:01:28
【问题描述】:
以下代码是我在项目中实现的 VisitorPattern 的简化版本。
#include <iostream>
class AVisitor {
public:
virtual void visit(class A *) = 0;
};
class ExtendedVisitor : public AVisitor {
public:
virtual void visit(class B *) = 0;
};
class A {
public:
virtual void accept(AVisitor *visitor) {
std::cout << "Call accept of A" << std::endl;
visitor->visit(this);
}
};
class B : public A {
public:
void accept(AVisitor *visitor) override {
std::cout << "Call accept of B" << std::endl;
B *just_this = this;
visitor->visit(just_this); //why this calls to visit(A*)
visitor->visit((B*) just_this); //useless casting
}
};
class ActualVisitor : public ExtendedVisitor {
public:
void visit(A *x) override {
std::cout << "Call visit on A*" << std::endl;
}
void visit(B *x) override {
std::cout << "Never called" << std::endl;
}
};
int main() {
ActualVisitor visitor;
A *a = new B();
a->accept(&visitor);
}
我不明白为什么B类的accept方法调用visitor(A*)方法而不是visitor(B*)。主函数打印
Call accept of B
Call visit on A*
Call visit on A*
相反,以下代码的行为符合我的预期:
#include <iostream>
class AVisitor {
public:
virtual void visit(class A *) = 0;
virtual void visit(class B *) = 0;
};
class A {
public:
virtual void accept(AVisitor *visitor) {
std::cout << "Call accept of A" << std::endl;
visitor->visit(this);
}
};
class B : public A {
public:
void accept(AVisitor *visitor) override {
std::cout << "Call accept of B" << std::endl;
B *just_this = this;
visitor->visit(just_this); //now it works
visitor->visit((B*) just_this);
}
};
class ActualVisitor : public AVisitor {
public:
void visit(A *x) override {
std::cout << "Call visit on A*" << std::endl;
}
void visit(B *x) override {
std::cout << "Call visit on B*" << std::endl;
}
};
int main() {
ActualVisitor visitor;
A *a = new B();
a->accept(&visitor);
}
现在打印:
Call accept of B
Call visit on B*
Call visit on B*
那么问题似乎是 AVisitor 类的继承。我想知道为什么会发生这种情况以及设计带有“专业”访问者的 VisitorPattern 的正确方法是什么(这里 ExtendedVisitor 也可以访问 B 对象)
【问题讨论】:
标签: c++ polymorphism abstract-class virtual-functions