【发布时间】:2019-12-17 10:36:14
【问题描述】:
我正在使用访问者模式来遍历和打印我正在操作的树的子节点。为了获得缩进打印,我以如下样式指定缩进级别:
printCurrent();
indentLevel(); // increases static variable
Visitor::visit(elem); // which then prints the children's node data
unindentLevel(); // decreases static variable
为了使这更好,我想实现一个函数,该函数采用 Visitor::visit 和参数 elem 并自动处理预操作 (indentLevel()) 和操作后 (unindentLevel())。
在实现该函数之前,我需要定义一个函数指针,该指针将用作函数的参数。但是,我未能指定指针的参数。作为一个例子,让我们看看从Visitor派生的PrintVisitor:
void PrintVisitor::visit(BinaryExpr &elem) {
std::cout << formatOutputStr({elem.getNodeName()});
this->incrementLevel();
Visitor::visit(elem); // <-- this is where I want to create a function pointer to
this->decrementLevel();
}
这个想法基本上是PrintVisitor 完成与打印相关的所有事情,所有其他逻辑(例如遍历逻辑)都在基类Visitor 中实现。因此,PrintVisitor::visit 需要执行其特定的操作(例如,通过 formatOutputStr 打印),然后执行 Visitor::visit 方法:
void PrintVisitor::visit(BinaryExpr &elem) {
std::cout << formatOutputStr({elem.getNodeName()});
void (Visitor::*myPt)(BinaryExpr&) = &Visitor::visit; // declare function pointer
executeIndented(myPt, elem); // pass function pointer myPt
}
// ...
void executeIndented("Function f", "FunctionArgs elem") {
// pre-action
this->incrementLevel();
// main action: call function pointer
(Visitor().*f)(elem); // call function pointer with arg
//post-action
this->decrementLevel();
}
我的目标是以某种方式实现在每个 PrintVisitor::visit 方法中始终调用前操作和后操作。为此,我认为将这些前置和后置操作封装到另一个函数 executeIndented 中是有意义的。
(Visitor().*myPt)(elem); 的语法在我看来有点奇怪,这真的是使用我的函数指针 myPt 调用带有参数 elem 的(基本)函数 Visitor::visit 的正确方法吗?
// 编辑
使用 (Visitor(*this).*myPt)(elem); 也可以。这两种方式有什么区别,哪一种是首选?
// EDIT2 希望现在对我要实现的目标的描述更加清晰。
【问题讨论】:
-
这能回答你的问题吗? C++ Call Pointer To Member Function
-
Visitor(*this)进行对象切片复制。Visitor()使用默认构造函数... -
@Patrick,这很重要,因为
Visitor(*this)是复制构造函数调用,Visitor()是上面提到的默认构造函数,所以两个对象可能有不同的状态(取决于那里的构造函数),这两个调用也是从PrintVisitor创建不同类型的Visitor对象是你想要的吗?或者您只想从PrintVisitor调用基类visit函数。我不确定我是否正确理解了您的原始问题。 -
@Patrick 从
PrintVisitor调用Visitor::visit(elem);?有什么问题,因为PrintVisitor派生自Visitor -
仅供参考:(我的回答)SO: Preorder traversal through Morse code BST,重点关注
BSTreeT::traverse()。
标签: c++ function-pointers