我一直在思考构造函数委托,以及如何有效地避免代码重复构造。
让我们考虑以下几点
代码示例101
Def cons被委托给,但是委托构造函数必须传递虚拟的空值。问题是它容易出错,而且混乱不堪。
class A
{
int a1;
double a2;
string a3;
DatabaseHandle* p;
public:
A(int i=0, double d=0.0, string s="") : a1(i), a2(d), a3(s) {
//open data base connection
}
A(int i) : A(i) {}
A(double d) : A(0,d) {}
A(string s) : A(0,0.0,s) {}
}代码示例102
语法要简洁得多,但效率不如101。委托构造者重新分配价值。
class A
{
int a1;
double a2;
string a3;
DatabaseHandle* p;
public:
A(int i=0, double d=0.0, string s="") : a1(i), a2(d), a3(s) {
//open database
}
A(int i) : A() { a1=i; }
A(double d) : A() { a2=d;}
A(string s) : A() { a3=s;}
}码样本103
与102相比没有任何改进,实际上需要一个额外的构造函数。所以代码更少倾斜。
class A
{
int a1 = 0;
double a2 = 0.0;
string a3 = "";
DatabaseHandle* p;
public:
A() { //open database
}
A(int i) : A() { a1=i; }
A(double d) : A() { a2=d;}
A(string s) : A() { a3=s;}
A(int i, double d, string s) : a1(i), a2(d), a3(s) {}
}问题:是否有方法修复此代码,以便(1)很少或没有代码重复(2)不需要将虚拟位置保持值传递给构造函数参数(3)不需要重新分配?
假设min C++版本是C++11。
备注/编辑:i添加了DatabaseHandle* p,以澄清def构造函数具有一些设置逻辑。我想澄清的是,建筑工人有一些共同的工作要做。如果这一点在最初的帖子中不清楚,我很抱歉。
发布于 2018-01-19 17:13:28
简单:
class A {
int a1 = 0;
double a2 = 0.0;
std::string a3 = "";
upDBHandle p = open_database(a1, a2, a3);
public:
A() = default;
explicit A(int i):a1(i) {}
explicit A(double d):a2(d) {}
explicit A(std::string s):a3(std::move(s)) {}
A(int i, double d, std::string s) : a1(i), a2(d), a3(std::move(s)) {}
};假设:
struct DatabaseHandle {};
using upDBHandle = std::unique_ptr<DatabaseHandle>;
upDBHandle open_database( int a, double d, std::string const& s ) {
return std::make_unique<DatabaseHandle>();
}或者同等的。
或者:
struct A_settings {
int a1 = 0;
double a2 = 0.0;
std::string a3 = "";
};
struct DatabaseHandle {};
using upDBHandle = std::unique_ptr<DatabaseHandle>;
upDBHandle open_database( int a, double d, std::string const& s ) {
return std::make_unique<DatabaseHandle>();
}
class A {
A_settings settings;
upDBHandle p = open_database(settings.a1, settings.a2, settings.a3);
public:
A() = default;
explicit A(A_settings s) : settings(std::move(s)) {}
};调用者可以创建各种有意义的A_settings工厂函数,如果他们想设置字段的子集。如果这没有任何好处,您可以将每个元素的参数移到它上。
发布于 2018-01-19 17:11:17
对于要应用的默认成员初始化器,不需要链接到默认构造函数。它们在不给它们显式初始化的任何构造函数中都会有效果。
class A
{
int a1 = 0;
double a2 = 0.0;
string a3 = "";
public:
A() {}
A(int i) : a1(i) {}
A(double d) : a2(d) {}
A(string s) : a3(s) {}
};https://stackoverflow.com/questions/48346095
复制相似问题