为什么'visitor pattern'要求每个类继承具有accept()函数的VisitorHost接口类?
Why does 'visitor pattern' asks each class to inherit VisitorHost interface class which has accept() function?
我正在学习一个设计模式,访问者模式,在c++中。
首先,我复制下面的两个实践代码。第一个是"我的测试代码",第二个是我课本中"正常访客模式"的简化代码。我想让你读第一个代码,但第二个只是一个正常的访问者模式的参考代码。
我的问题是为什么访问者模式要求每个类继承VisitorsHostInterface类,该类具有虚拟函数accept();如有需要,请参阅下面的第二个代码"正常访客模式"。在我的理解中,没有必要使用accept()函数来扫描所有实例,如第一个代码,"我的测试代码"。我认为"我的测试代码"比"正常的访问者模式"更简单。请告诉我为什么访问者模式要求接受()函数到每个类?非常感谢。
(1)我的测试代码class ClassD;
class ClassC {
public:
ClassC(int new_value, ClassD* new_next_object) : value_(new_value), next_object_(new_next_object) {};
void print() { std::cout << "ClassC value_ = " << value_ << std::endl; }
int value() { return value_; }
std::shared_ptr<ClassD> next_object(void) { return next_object_; }
private:
int value_=0;
std::shared_ptr<ClassD> next_object_;
};
class ClassD {
public:
ClassD(int new_value, ClassC* new_next_object) : value_(new_value), next_object_(new_next_object) {};
void print() { std::cout << "ClassD value_ = " << value_ << std::endl; }
int value() { return value_; }
std::shared_ptr<ClassC> next_object(void) { return next_object_; }
private:
int value_=0;
std::shared_ptr<ClassC> next_object_;
};
class VisitorFuncInterface {
public:
virtual ~VisitorFuncInterface() = default;
virtual void visit(ClassC* obj) = 0;
virtual void visit(ClassD* obj) = 0;
};
class VisitorFunc : public VisitorFuncInterface {
public:
virtual ~VisitorFunc() = default;
void visit(ClassC* obj) {
if (obj) {
obj->print();
this->visit(obj->next_object().get());
}
}
void visit(ClassD* obj) {
if (obj) {
obj->print();
this->visit(obj->next_object().get());
}
}
};
void test_visitor_without_host(void) {
ClassD* d0 = new ClassD(0, nullptr);
ClassC* c0 = new ClassC(1, d0);
ClassD* d1 = new ClassD(2, c0);
VisitorFunc v;
v.visit(d1);
delete d1;
}
test_visitor_without_host()的结果如下:
ClassD value_ = 2
ClassC value_ = 1
ClassD value_ = 0
(2)正常访客模式代码
class ClassA;
class ClassB;
class VisitorInterface {
public:
virtual ~VisitorInterface() = default;
virtual void visit(ClassA* obj) = 0;
virtual void visit(ClassB* obj) = 0;
};
class VisitorsHostInterface { // = visitor's host
public:
virtual ~VisitorsHostInterface() = default;
virtual void accept(VisitorInterface& v) = 0;
};
class VisitorsHost : public VisitorsHostInterface {
public:
virtual ~VisitorsHost();
void accept(VisitorInterface& v) {};
};
class ClassA : public VisitorsHostInterface {
public:
ClassA(int new_value, ClassB* new_next_object) : value_(new_value), next_object_(new_next_object) {};
void print() { std::cout << "ClassA value_ = " << value_ << std::endl; }
int value() { return value_; }
std::shared_ptr<ClassB> next_object(void) { return next_object_; }
void accept(VisitorInterface& v) { v.visit(this); };
private:
int value_=0;
std::shared_ptr<ClassB> next_object_;
};
class ClassB : public VisitorsHostInterface {
public:
ClassB(int new_value, ClassA* new_next_object) : value_(new_value), next_object_(new_next_object) {};
void print() { std::cout << "ClassB value_ = " << value_ << std::endl; }
int value() { return value_; }
std::shared_ptr<ClassA> next_object(void) { return next_object_; }
void accept(VisitorInterface& v) { v.visit(this); };
private:
int value_=0;
std::shared_ptr<ClassA> next_object_;
};
class Visitor : public VisitorInterface {
public:
virtual ~Visitor() = default;
void visit(ClassA* obj) {
if (obj) {
obj->print();
this->visit(obj->next_object().get());
}
}
void visit(ClassB* obj) {
if (obj) {
obj->print();
this->visit(obj->next_object().get());
}
}
};
void test_visitor(void) {
ClassB* b0 = new ClassB(0, nullptr);
ClassA* a0 = new ClassA(1, b0);
ClassB* b1 = new ClassB(2, a0);
Visitor v;
b1->accept(v);
delete b1;
}
test_visitor()的结果如下:
ClassB value_ = 2
ClassA value_ = 1
ClassB value_ = 0
在您的示例中,您按值保存所有对象并知道它们的静态&动态类型。您不需要动态分派,因此您不需要有一个通用的VisitorsHostInterface
基类。所需要做的就是让你的类实现一个accept
函数。
vecotr<unique_ptr<Widget>>
。其中许多不同的Widget
子类型通过指针存储。Widget
及其每一个子类必须实现虚accept
函数。要获得对象的动态类型,需要执行动态分派。
相关文章:
- "error: no matching function for call to"构造函数错误
- 什么时候调用组成单元对象的析构函数
- 继承函数的重载解析
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- C++模板来检查友元函数的存在
- 递归函数计算序列中的平方和(并输出过程)
- 对RValue对象调用的LValue ref限定成员函数
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 为什么使用 "this" 指针调用派生成员函数?
- 将对象数组的引用传递给函数
- 函数调用中参数的顺序重要吗
- 函数向量_指针有不同的原型,我可以构建一个吗
- 使用不带参数的函数访问结构元素
- 代码在main()中运行,但在函数中出现错误
- 内置函数可查看CPP中的成员变量
- Unix accept()函数两次返回相同的文件描述符
- 为什么'visitor pattern'要求每个类继承具有accept()函数的VisitorHost接口类?
- Qt对话框如何从函数中触发accept()和reject()