bsoundra
bsoundra

Reputation: 970

C++ constructor syntax explaination

I was going through a tutorial for building an AST with the help of Clang/LLVM.

I see this syntax there:

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;
};

And:

//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.
  }

Please let me know if there is any other material which would be of good help and learning experience. Thanks

Upvotes: 2

Views: 290

Answers (3)

Joshua Rodgers
Joshua Rodgers

Reputation: 5404

These are constructor initializers. They initialized class members with the value given to them. For instance:

class TestClass
{
private:
    int someField;

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

Will initialize the member someField to have a value of 5 during the call to the TestClass() constructor. You can separate multiple initializers with a , to initialize multiple members. You can also pass parameters from the constructor to these initializers such as:

class TestClass
{
private:
    int someField;

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

When this constructor is called, the value passed to _someField will be used to initialize someField.

Also consider inheritance. Using the second TestClass as our base we get the following derived type:

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

That's how you can construct a base class from a derived type and pass parameters to a non-default constructor. Without this you wouldn't be able to construct the base with the appropriate parameters using a non-default constructor.

Upvotes: 2

Marlon
Marlon

Reputation: 20332

It's called a constructor initialization list, which is used for inheritance and initializating member variables. Click this link for a good explanation of this topic.

One scenario this is required is dealing with inheritance. Consider the following:

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)
    {
    }
};

How can we change the above to compile? With a constructor initialization list:

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

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

Upvotes: 1

fnokke
fnokke

Reputation: 1161

This constructur is in the format

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

where you can exchange initConstructor to the initialization constructors of the PPContext members

Upvotes: 0

Related Questions