Can I call a constructor from another constructor (do constructor chaining) in C++?

前端 未结 15 2319
暖寄归人
暖寄归人 2020-11-22 01:27

As a C# developer I\'m used to running through constructors:

class Test {
    public Test() {
        DoSomething();         


        
相关标签:
15条回答
  • 2020-11-22 01:31

    No, you can't call one constructor from another in C++03 (called a delegating constructor).

    This changed in C++11 (aka C++0x), which added support for the following syntax:
    (example taken from Wikipedia)

    class SomeType
    {
      int number;
    
    public:
      SomeType(int newNumber) : number(newNumber) {}
      SomeType() : SomeType(42) {}
    };
    
    0 讨论(0)
  • 2020-11-22 01:31

    If you want to be evil, you can use the in-place "new" operator:

    class Foo() {
        Foo() { /* default constructor deliciousness */ }
        Foo(Bar myParam) {
          new (this) Foo();
          /* bar your param all night long */
        } 
    };
    

    Seems to work for me.

    edit

    As @ElvedinHamzagic points out, if Foo contained an object which allocated memory, that object might not be freed. This complicates things further.

    A more general example:

    class Foo() {
    private:
      std::vector<int> Stuff;
    public:
        Foo()
          : Stuff(42)
        {
          /* default constructor deliciousness */
        }
    
        Foo(Bar myParam)
        {
          this->~Foo();
          new (this) Foo();
          /* bar your param all night long */
        } 
    };
    

    Looks a bit less elegant, for sure. @JohnIdol's solution is much better.

    0 讨论(0)
  • 2020-11-22 01:36

    Simply put, you cannot before C++11.

    C++11 introduces delegating constructors:

    Delegating constructor

    If the name of the class itself appears as class-or-identifier in the member initializer list, then the list must consist of that one member initializer only; such constructor is known as the delegating constructor, and the constructor selected by the only member of the initializer list is the target constructor

    In this case, the target constructor is selected by overload resolution and executed first, then the control returns to the delegating constructor and its body is executed.

    Delegating constructors cannot be recursive.

    class Foo {
    public: 
      Foo(char x, int y) {}
      Foo(int y) : Foo('a', y) {} // Foo(int) delegates to Foo(char,int)
    };
    

    Note that a delegating constructor is an all-or-nothing proposal; if a constructor delegates to another constructor, the calling constructor isn't allowed to have any other members in its initialization list. This makes sense if you think about initializing const/reference members once, and only once.

    0 讨论(0)
  • 2020-11-22 01:37

    It is worth pointing out that you can call the constructor of a parent class in your constructor e.g.:

    class A { /* ... */ };
    
    class B : public A
    {
        B() : A()
        {
            // ...
        }
    };
    

    But, no, you can't call another constructor of the same class.

    0 讨论(0)
  • 2020-11-22 01:40

    If I understand your question correctly, you're asking if you can call multiple constructors in C++?

    If that's what you're looking for, then no - that is not possible.

    You certainly can have multiple constructors, each with unique argument signatures, and then call the one you want when you instantiate a new object.

    You can even have one constructor with defaulted arguments on the end.

    But you may not have multiple constructors, and then call each of them separately.

    0 讨论(0)
  • 2020-11-22 01:41

    No, in C++ you cannot call a constructor from a constructor. What you can do, as warren pointed out, is:

    • Overload the constructor, using different signatures
    • Use default values on arguments, to make a "simpler" version available

    Note that in the first case, you cannot reduce code duplication by calling one constructor from another. You can of course have a separate, private/protected, method that does all the initialization, and let the constructor mainly deal with argument handling.

    0 讨论(0)
提交回复
热议问题