繁体   English   中英

高效的施工委托

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM