C++ C++;避免常量和非常量访问的代码重复
我有一个类,它应该为每个成员变量调用一个visitor方法。大概是这样的:C++ C++;避免常量和非常量访问的代码重复,c++,const-correctness,visitor-pattern,C++,Const Correctness,Visitor Pattern,我有一个类,它应该为每个成员变量调用一个visitor方法。大概是这样的: class A{ int a, b, c; public: void accept(Visitor &visitor){ visitor.visit(a); visitor.visit(b); visitor.visit(c); } }; 如何使用相同的代码获得void accept()const方法而不需要代码重复 复制的明显解决方案是
class A{
int a, b, c;
public:
void accept(Visitor &visitor){
visitor.visit(a);
visitor.visit(b);
visitor.visit(c);
}
};
如何使用相同的代码获得void accept()const
方法而不需要代码重复
复制的明显解决方案是添加一种方法:
void accept(Visitor &visitor) const {
visitor.visit(a);
visitor.visit(b);
visitor.visit(c);
}
该方法具有我想要的含义,但我希望避免代码重复。使用这两种方法的原因是能够通过“读取”访问者读取变量,并让
accept
方法很好地const
。然后,非常量accept
可以用于“写入/更新”访问者。您可以创建一个类静态模板帮助函数,该函数将根据您提供给它的指针的类型推断常量。像这样:
class A{
int a, b, c;
public:
void accept(Visitor &visitor){
acceptImpl(*this, visitor);
}
void accept(Visitor &visitor) const{
acceptImpl(*this, visitor);
}
private:
template<typename t_A>
static void acceptImpl(t_A& aObj, Visitor &visitor)
{
visitor.visit(aObj.a);
visitor.visit(aObj.b);
visitor.visit(aObj.c);
}
};
A类{
INTA、b、c;
公众:
无效接受(访客和访客){
acceptImpl(*本,访客);
}
无效接受(访客和访客)常量{
acceptImpl(*本,访客);
}
私人:
模板
静态void acceptImpl(t_A&aObj、访问者和访问者)
{
访客访问(aObj.a);
访客访问(aObj.b);
访客访问(aObj.c);
}
};
模板帮助程序:
class A{
int a, b, c;
private:
template <typename T>
static void do_visiting(T &self, Visitor &visitor) {
visitor.visit(self.a);
visitor.visit(self.b);
visitor.visit(self.c);
}
public:
void accept(Visitor &visitor) {
do_visiting(*this, visitor); // calls do_visiting<A>
}
void accept(Visitor &visitor) const {
do_visiting(*this, visitor); // calls do_visiting<const A>
}
};
A类{
INTA、b、c;
私人:
模板
静态无效访问(T&self、访客和访客){
访问者访问(self.a);
访问者访问(self.b);
访问者访问(self.c);
}
公众:
无效接受(访客和访客){
do_Visition(*这个,访客);//呼叫do_Visition
}
无效接受(访客和访客)常量{
do_Visition(*这个,访客);//呼叫do_Visition
}
};
代码复制发生在何处。信息不足。访问的签名是什么?如果它是常量,那么就不需要非常量accept
。如果不是,那么这个accept
不能是常量。你不能在当前的accept
方法上加一个const
?为什么需要非常量版本的accept?@Beta:可能是const
重载了visit()
,而非const
@Beta:Visitor::visit
可以在const int&
参数上重载,后者可能会修改所访问的对象。不确定这是否明智,但提问者当前的重复代码允许这样做。