我有以下代码:
class A{};
class B: public A{};
class C: public A{};
class MyVisitor
{
public:
void visit(B*);
void visit(C*);
};
然后收集A *对象,我想实现以下目标:
1)
MyVisitor visitor;
for(vector<A*>::iterator it = vec.begin(); it!= vec.end();it++)
visitor->visit(a);
2)以某种方式确定在编译时,如果A *指向派生对象D,并且如果MyVisitor::visit(D*)
函数不存在则给出编译器错误
我知道1)可以通过一些多方法实现来实现,我想我可以找到一些c ++的多方法实现。但是在某种程度上可能吗?
答案 0 :(得分:2)
您可以像这样使用dynamic_cast
(在for
循环体内),因为行为应该在运行时变化(根据实际的数据类型)。
ClassB* ba = dynamic_cast<ClassB*>(a);
if (ba)
visitor->visit(ba);
ClassC* ca = dynamic_cast<ClassC*>(a);
if (ca)
visitor->visit(ca);
也许您的visit
函数可能会被声明为virtual
(对于您的ClassD
事物。)
否则将您的类组织为类的树(而不是林),并拥有最顶层的根类
class Topmost {
virtual int classnum() const;
并采用约定,每个非抽象类给出其唯一的classnum
等...或者具有元类机制(例如Qt已经有)
答案 1 :(得分:1)
也许你想看看这个:http://www.yorel.be/mm/,https://github.com/jll63/yomm11,http://www.codeproject.com/Articles/635264/Open-Multi-Methods-for-Cplusplus11-Part-1
它是C ++多方法的一种实现,非常类似于Stroustrup&amp;提案。它也很快,它胜过双重调度。
答案 2 :(得分:0)
你可以尝试这样的事情。
#include <iostream>
class A
{
virtual void visit() = 0;
};
class B: private A
{
public:
void visit()
{
std::cout << __PRETTY_FUNCTION__ << "\n";
}
};
class C: private A
{
public:
void visit()
{
std::cout << __PRETTY_FUNCTION__ << "\n";
}
};
template <typename... Args>
class MyVisitor : public Args...
{
public:
template <typename T>
void visit(T* t)
{
t->visit();
}
};
int main()
{
MyVisitor<B, C> visitor;
B b;
B* bp = &b;
visitor.visit(bp);
return 0;
}
答案 3 :(得分:0)
您可以完整地应用访客模式:
class B;
class C;
class IVisitor
{
public:
void visit(B&) = 0;
void visit(C&) = 0;
};
class A
{
virtual ~A() = default;
virtual void accept(IVisitor& v) = 0;
};
class B: public A{ void accept(IVisitor& v) override { v.visit(*this); } };
class C: public A{ void accept(IVisitor& v) override { v.visit(*this); } };