C ++构造函数语法解释

时间:2011-02-25 21:24:05

标签: c++ syntax clang

我正在经历a tutorial for building an AST with the help of Clang/LLVM

我在那里看到了这种语法:

struct PPContext {
  // Takes ownership of client.
  PPContext(clang::DiagnosticClient* client = 0,
            const std::string& triple = LLVM_HOSTTRIPLE)
    : diagClient(client == 0?new clang::TextDiagnosticPrinter:client),
      diags(diagClient),
      target(clang::TargetInfo::CreateTargetInfo(triple)),
      headers(fm),
      pp(diags, opts, *target, sm, headers)
  {
    // Configure warnings to be similar to what command-line `clang` outputs
    // (see tut03).
    // XXX: move warning initialization to libDriver
    using namespace clang;
    diags.setDiagnosticMapping(diag::kind,diag::MAP_IGNORE);
//diag::warn_pp_undef_identifier was the initial value instead of diag::kind. But I changed since it gave error.
  }

  ~PPContext()
  {
    delete diagClient;
    delete target;
  }

  clang::DiagnosticClient* diagClient;
  clang::Diagnostic diags;
  clang::LangOptions opts;
  clang::TargetInfo* target;
  clang::SourceManager sm;
  clang::FileManager fm;
  clang::HeaderSearch headers;
  clang::Preprocessor pp;
};

//What is the constructor doing here ? The construct looks very different and difficult to comprehend !!!
// Could someone break it up for me ?
PPContext(clang::DiagnosticClient* client = 0,
            const std::string& triple = LLVM_HOSTTRIPLE)
    : diagClient(client == 0?new clang::TextDiagnosticPrinter:client),
      diags(diagClient),
      target(clang::TargetInfo::CreateTargetInfo(triple)),
      headers(fm),
      pp(diags, opts, *target, sm, headers)
  {
    // Configure warnings to be similar to what command-line `clang` outputs
    // (see tut03).
    // XXX: move warning initialization to libDriver
    using namespace clang;
    diags.setDiagnosticMapping(diag::kind,diag::MAP_IGNORE);
//diag::warn_pp_undef_identifier was the initial value instead of diag::kind. But I changed since it gave error.
  }

如果有任何其他材料可以提供很好的帮助和学习经验,请告诉我。感谢

3 个答案:

答案 0 :(得分:2)

这些是构造函数初始值设定项。他们用赋予它们的值初始化了类成员。例如:

class TestClass
{
private:
    int someField;

public:
    TestClass() : someField(5) { }
};

在调用TestClass()构造函数期间,将成员someField初始化为值5。您可以使用,分隔多个初始值设定项以初始化多个成员。您还可以将构造函数中的参数传递给这些初始值设定项,例如:

class TestClass
{
private:
    int someField;

public:
    TestClass(int _someField) : someField(_someField) { }
};

调用此构造函数时,传递给_someField的值将用于初始化someField。

还要考虑继承。使用第二个TestClass作为基础,我们得到以下派生类型:

class TestClassDerived : public TestClass
{
public:
    TestClassDerived(int _someField) : TestClass(_someField) { }
};

这就是如何从派生类型构造基类并将参数传递给非默认构造函数的方法。如果没有这个,您将无法使用非默认构造函数构造具有适当参数的基础。

答案 1 :(得分:1)

它被称为构造函数初始化列表,用于继承和初始化成员变量。 点击this link以获得有关此主题的详细说明。

这需要的一个方案是处理继承。请考虑以下事项:

class Base
{
public:
    Base(int n)
    {
    }
};

class Derived : Base
{
public:
    // Error! How do we construct Base? We never pass n
    // to the constructor of Base.
    Derived(int n)
    {
    }
};

我们怎样才能改变上面的编译?使用构造函数初始化列表:

class Base
{
public:
    Base(int n)
    {
    }
};

class Derived : Base
{
public:
    // Now your compiler is happy.
    Derived(int n) : Base(n)
    {
    }
};

答案 2 :(得分:0)

此构造符的格式为

PPContext(arg1, arg2)
    : initConstructor1,
      ...,
      initConstructor5

您可以将init Constructor交换到的初始化构造函数 APPContext成员