[英]Efficient construction delegation
我一直在思考构造函数委托,以及如何在没有代码重复构造的情况下有效地进行工作。
让我们考虑以下
代码样本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的改进,实际上需要1个额外的构造函数。 因此更少的代码精益。
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)不需要重新分配?
假定最小C ++版本是C ++ 11。
注/编辑:我添加了DatabaseHandle * p,以阐明def构造函数具有一些设置逻辑。 我想澄清一下,构造函数需要完成一些常见的工作。 如果在原始帖子中不清楚此内容,我深表歉意。
无需链接到默认构造函数即可应用默认成员初始化程序。 它们将在任何没有为其提供显式初始化程序的构造函数中起作用。
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) {}
};
简单:
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
工厂函数。 如果那不好,您可以将每个元素的ctor移到它上面。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.