I have a class Foo with 2 constructors, A and B.
Constructor B contains some important setup code and should always be run when an object is instantiated.
At the end of constructor A, I want to execute the important setup code that is inside B.
Below is an example of the described setup which involves connecting to a database.
class Foo {
public:
// Constructor A
Foo(std::string db_path) {
// ... Some input validation and retry logic for opening the database.
Database db = ...
// ...
Foo(db); // Impossible to directly call another constructor from the body of a constructor.
}
// Constructor B
Foo(Database db)
: db_(db) {
// ... Some important setup code.
}
private:
Database db_;
};
I believe it isn’t possible to call a constructor from another constructor’s body in C like you can in other languages such as C#.
I know that C 11 has the ‘delegating constructors’ feature, however I don’t believe I can make use of this because I have to perform tasks such as input validation and setting up retry logic in the body of constructor A.
One alternative that has been suggested here is to extract out the important setup code in constructor B into a private init method and have both constructors just call that init method.
This works well for my use case, however I am wondering if there is a modern way of accomplishing constructor chaining in C .
Thanks!
CodePudding user response:
You can call constructors from constructors, like this : (The constructor with string parameter calls the constructor with int parameter)
#include <cassert>
#include <string>
class Foo
{
public:
explicit Foo(int value) :
m_value{ value }
{
};
explicit Foo(const std::string& value) :
Foo(std::stoi(value))
{
}
int value() const
{
return m_value;
}
private:
int m_value;
};
int main()
{
Foo f1(42);
Foo f2("42");
assert(f1.value() == f2.value());
return 0;
}
CodePudding user response:
You could create a private function (or a free function with internal linkage) to initialize the parameters to your delegate constructor. For example:
class Foo {
private:
Database connect_to_db(const std::string& db_path) {
// Validation and retry logic
}
public:
Foo(const std::string& db_path)
: Foo{connect_to_db(db_path)}
{}
Foo(Database db)
: db_{db}
{
// Important setup code
}
private:
Database db_;
};
