这个类是如何构造的

How is this class constructed?

本文关键字:何构造      更新时间:2023-10-16

我很困惑该类如何通过将自身作为模板参数传递来继承类 RecursiveASTVisitor 。另外,是否在行
中写入重写(R)

MyRecursiveASTVisitor(Rewriter &R) : Rewrite(R) { }

将值 R 分配给变量重写?代码中任何地方都没有定义类重写。":" 运算符是否用于从类继承以外的其他内容?

class MyRecursiveASTVisitor
    : public RecursiveASTVisitor<MyRecursiveASTVisitor>
{
 public:
  MyRecursiveASTVisitor(Rewriter &R) : Rewrite(R) { }
  void InstrumentStmt(Stmt *s);
  bool VisitStmt(Stmt *s);
  bool VisitUnaryOperator(UnaryOperator *e);
  Rewriter &Rewrite;
};

它被称为奇怪的重复模板模式。当编译器创建RecursiveASTVisitor<MyRecursiveASTVisitor>它知道MyRecursiveASTVisitor的布局时,所以一切都没问题。

您可以在维基百科上阅读更多信息

正如评论所提到的,这被称为奇怪的重复模板模式。此模式通常用于提供类似于虚函数的机制,但在编译时(静态多态性)。例如,RecursiveASTVistor<T>可能包含执行以下操作的方法:

...
//using T = MyRecursiveASTVisitor; for your specific case
T *concrete_visitor = static_cast<T*>(this);
concrete_visitor->VisitStmt(something);

如果在 MyRecursiveASTVisitor 类中定义了 VisitStmt,则调用该方法,否则调用 RecursiveASTVistor 提供的基本定义。类层次结构之外的调用方也可以利用这种静态多态性。

这里有一个简短的例子,可以帮助你更好地了解正在发生的事情:

#include <iostream> 
template <class T>
struct Base {
    void foo() {
        T *concrete = static_cast<T*>(this);
        concrete->foo();
    };
    void bar() {std::cout << "Base" << std::endl; }
};
struct Derived : public Base<Derived> {
    void foo() {std::cout << "Derived" << std::endl;}
};
int main() {
    Base<Derived> b;
    b.foo();
    b.bar();
}

输出

Derived
Base

编辑:要回答您的其他问题:

另外,是否在行中写入重写(R) MyRecursiveASTVisitor(Rewriter &R) : Rewrite(R) { }分配值 R 到变量重写?任何地方都没有定义类重写 在代码中。":"运算符是否用于继承以外的其他内容 来自班级?

RewriteMyRecursiveASTVisitor 类的成员变量,是对类型 Rewriter 的对象的引用。:运算符在构造函数的定义中用于表示成员初始值设定项列表。在这种情况下,我们只需使用传入的参数 R 初始化 Rewrite 变量。需要明确的是,MyRecursiveASTVisitor(Rewriter &R) : Rewrite(R) { }是类MyRecursiveASTVisitor的构造函数定义,它不是类定义。