Can I call a constructor from another constructor (do constructor chaining) in C++?
C++11: Yes!
C++11 and onwards has this same feature (called delegating constructors).
The syntax is slightly different from C#:
class Foo {
public:
Foo(char x, int y) {}
Foo(int y) : Foo('a', y) {}
};
C++03: No
Unfortunately, there's no way to do this in C++03, but there are two ways of simulating this:
You can combine two (or more) constructors via default parameters:
class Foo {
public:
Foo(char x, int y=0); // combines two constructors (char) and (char, int)
// ...
};Use an init method to share common code:
class Foo {
public:
Foo(char x);
Foo(char x, int y);
// ...
private:
void init(char x, int y);
};
Foo::Foo(char x)
{
init(x, int(x) + 7);
// ...
}
Foo::Foo(char x, int y)
{
init(x, y);
// ...
}
void Foo::init(char x, int y)
{
// ...
}
See the C++FAQ entry for reference.
Can constructor call another constructor in c++?
Not before C++11.
Extract the common functionality into a separate function instead. I usually name this function construct().
The "so-called" second call would compile, but has a different meaning in C++: it would construct a new object, a temporary, which will then be instantly deleted at the end of the statement. So, no.
A destructor, however, can be called without a problem.
Call constructor with different argument types from another constructor in C++17
Yes, you can define one constructor in terms of another. No, I don't think you can do it without some additional function.
A constructor which invokes another constructor of the same class is called a "delegating constructor", and uses the same sort of syntax as a member initializer list, but using the class's own name instead of its base classes and members:
ClassName::ClassName(SomeParam1 p1, SomeParam2 p2)
: ClassName(arg_expr1, arg_expr2, arg_expr3)
{ /* any other logic after the target constructor finishes */ }
But this case is a bit tricky because of the need for the intermediate object date_as_struct
. Or with the updated question, just the need to do some parsing before entering another constructor. I'd solve this one by making an additional private constructor which takes the Date_as_struct
:
class Date {
public:
explicit Date(int day = 1, int month = 1, int year = 0);
explicit Date(const string &date_as_string);
/* ... */
private:
struct Date_as_struct {
int day;
int month;
int year;
};
explicit Date(const Date_as_struct&);
static Date_as_struct ParseStringContainingDate(const std::string&);
};
Date_as_struct
and ParseStringContainingDate
are declared here as private, since it sounds like nothing else will really use them.
Then for the string constructor, you just have
Date::Date(const std::string& date_as_string)
: Date(ParseStringContainingDate(date_as_string))
{}
The Date(const Date_as_struct&)
constructor can very easily delegate to Date(int, int, int)
or vice versa, whichever is more natural for the actual member initialization.
Call one constructor from another
Like this:
public Sample(string str) : this(int.Parse(str)) { }
Constructor chaining in C++
The paragraph basically says this:
class X
{
void Init(params) {/*common initing code here*/ }
X(params1) { Init(someParams); /*custom code*/ }
X(params2) { Init(someOtherParams); /*custom code*/ }
};
You cannot call a constructor from a member function either. It may seem to you that you've done it, but that's an illusion:
class X
{
public:
X(int i):i(i){}
void f()
{
X(3); //this just creates a temprorary - doesn't call the ctor on this instance
}
int i;
};
int main()
{
using std::cout;
X x(4);
cout << x.i << "\n"; //prints 4
x.f();
cout << x.i << "\n"; //prints 4 again
}
Calling another constructor C++
Simply call a delegating constructor. Use a helper function to construct the vector<item>
.
namespace {
vector<item> helper(char*buff, size_t num)
{
/* your implementation for re-packaging the data here */
}
}
Foo::Foo(char*buff, size_t num)
: Foo(helper(buff,num))
{}
Call constructor inside a call to another constructor
The problem is that B b(A(i));
is a function declaration and not a declaration for a variable named b
of type B
.
This is due to what is called most vexing parse. In particular, the statement:
B b(A(i)); //this is a declaration for a function named `b` that takes parameter of type A and has no return type
the above is a declaration for a function named b
that takes one parameter of type A
and with return type of B
.
To solve this, you can either use curly braces {}
or double ()
to solve this:
Method 1
Use {}
around A(i)
.
//----v----v------->declares a variable of type B and is not a function declaration
B b{A(i)};
Method 2
Use double parenthesis (())
.
//-v--------v------>declares a variable of type B and is not a function declaration
B b( (A(i)) );
Related Topics
How to Determine Opencv Version
How to Have All the Inputs on the Same Line C++
Count How Many Times Elements in an Array Are Repeated
Fastest Way to Check If a File Exists Using Standard C++/C++11,14,17/C
How to Align Text to the Right Using Cout
Vector Converted All Negative Values to Zero
How to Install (V142) Build Tools in Visual Studio
Most Efficient Way of Copying a Raw Byte Array into an Empty Byte Vector
Escape Sequence \F - Form Feed - What Exactly Is It
Define Preprocessor Macro Through Cmake
How to Determine the Boost Version on a System
How to Properly Clean Up Elements from Vectors of Object Pointers
Automatically Add All Files in a Folder to a Target Using Cmake
How to Check Whether a String Contains Every Letter in the Alphabet in C++