首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >高效施工委托

高效施工委托
EN

Stack Overflow用户
提问于 2018-01-19 17:03:46
回答 2查看 93关注 0票数 0

我一直在思考构造函数委托,以及如何有效地避免代码重复构造。

让我们考虑以下几点

代码示例101

Def cons被委托给,但是委托构造函数必须传递虚拟的空值。问题是它容易出错,而且混乱不堪。

代码语言:javascript
复制
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。委托构造者重新分配价值。

代码语言:javascript
复制
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相比没有任何改进,实际上需要一个额外的构造函数。所以代码更少倾斜。

代码语言:javascript
复制
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构造函数具有一些设置逻辑。我想澄清的是,建筑工人有一些共同的工作要做。如果这一点在最初的帖子中不清楚,我很抱歉。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-01-19 17:13:28

简单:

代码语言:javascript
复制
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)) {}
};

假设:

代码语言:javascript
复制
struct DatabaseHandle {};

using upDBHandle = std::unique_ptr<DatabaseHandle>;

upDBHandle open_database( int a, double d, std::string const& s ) {
  return std::make_unique<DatabaseHandle>();
}

或者同等的。

或者:

代码语言:javascript
复制
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工厂函数,如果他们想设置字段的子集。如果这没有任何好处,您可以将每个元素的参数移到它上。

票数 1
EN

Stack Overflow用户

发布于 2018-01-19 17:11:17

对于要应用的默认成员初始化器,不需要链接到默认构造函数。它们在不给它们显式初始化的任何构造函数中都会有效果。

代码语言:javascript
复制
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) {}
};
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48346095

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档