我怎样才能写出干净利落的c++构造函数?
Posted
技术标签:
【中文标题】我怎样才能写出干净利落的c++构造函数?【英文标题】:How could I write c++ construction function clean and clear? 【发布时间】:2020-04-16 03:07:24 【问题描述】:假设我的班级是这样的:
class Strt
public:
int a0;
int b0;
Strt(int a, int b): a(a), b(b)
Strt(Strt& s) a = s.a; b = s.b; // these two functions have same contents
Strt(Strt&& s) a = s.a; b = s.b;
;
问题是左值初始化和右值初始化是相同的,这使得它不干净,因为一旦我想修改类成员变量,我需要以相同的方式修改这两个函数。代码是重复的。我怎样才能把它清理干净以便更好地阅读和维护?
编辑:
有些场合会调用这些构造函数:
Strt func() return Strt(1, 2);
vector<Strt> v;
Strt s(3, 4);
v.push_back(s); // call left construction function
v.emplace_back(func(); // call right construction function
还有一些场合需要修改类,比如我需要在里面添加int c;
的新字段:
class Strt
public:
int a0;
int b0;
int c0;
Strt(int a, int b, int c): a(a), b(b), c(c)
Strt(Strt& s) a = s.a; b = s.b; c = s.c; // The two functions are duplicatedly modified in the same way
Strt(Strt&& s) a = s.a; b = s.b; c = s.c;
;
Strt(Strt&)
和Strt(Strt&&)
的内容是否相同,我必须分别修改吗?
【问题讨论】:
您的问题含糊不清。您能否列出构造函数的期望用法及其预期结果?此外,您可能希望将类和属性重命名为更具解释性的命名约定,这是最佳实践。 有用的阅读:The rule of three/five/zero。详细说明何时需要特殊的复制和分配功能以及原因。 【参考方案1】:由于您的类不拥有任何可移动资源,因此没有理由创建单独的复制和移动构造函数。单个复制构造函数将执行相同的操作:
class Strt
public:
int a0;
int b0;
Strt(int a, int b): a(a), b(b)
Strt(const Strt& s): a(s.a), b(s.b)
;
Live Demo
当然,因为你的拷贝构造函数除了成员拷贝之外什么都不做,你可以省略它,让编译器为你生成默认的:
class Strt
public:
int a0;
int b0;
Strt(int a, int b): a(a), b(b)
;
Live Demo
由于a
和b
都是公共的,并且您除了从构造函数参数初始化它们之外什么都不做,您可以完全省略您的构造函数并使用聚合初始化:
class Strt
public:
int a0;
int b0;
;
Live Demo
【讨论】:
你好,你好像只用
构造对象,那我用()
构造呢?我还不需要构造函数吗?
你必须使用统一的初始化语法(使用
)来进行聚合初始化。它被称为“统一”是有原因的。其目的是将聚合、数组、对象的初始化语法与用户定义的构造函数统一起来。【参考方案2】:
最干净的解决方案是删除用户声明的构造函数。不需要它们:
class Strt
public:
int a0;
int b0;
;
【讨论】:
为什么?我还需要删除Strt(int a, int b)
吗?
你不需要。但是如果你这样做,课程会更简单。越简单越好。
是否支持这样的初始化:Strt s(1, 2);
如果我删除它?
否,但它会允许Strt s1, 2;
【参考方案3】:
在您的情况下,您可能会默认或省略您的复制/移动构造函数:
class Strt
public:
int a0;
int b0;
Strt(int a, int b): a(a), b(b)
Strt(const Strt&) = default;
Strt(Strt&&) = default;
;
一般情况下,您可以使用委托constructor:
class Strt
public:
int a0;
int b0;
Strt(int a, int b): a(a), b(b)
Strt(const Strt& rhs) : Strt(rhs.a, rhs.b)
Strt(Strt&& rhs) : Strt(rhs)
;
【讨论】:
以上是关于我怎样才能写出干净利落的c++构造函数?的主要内容,如果未能解决你的问题,请参考以下文章
必须公开聚合字段构造函数才能在 C++ 中使用聚合初始化吗?