如何正确编写构造函数代码
How to correctly write a constructor code?
例如,我有一个类定义:
#include <string>
using std::string;
class human
{
public:
human(string, string);
private:
string firstName, secondName;
};
这些描述构造函数的方式有区别吗?
human::human(string fname, string sname)
{
firstName = fname;
secondName = sname;
}
human::human(string fname, string sname)
:firstName(fname), secondName(sname){}
是的,这是有区别的。假设你有一个不可构造的类
class NTCClass {
int i;
public:
NTCClass(int i) : i(i) {}
};
如果这个类是另一个类的成员,则必须使用第二种形式的初始化:
class Wrapper {
NTCClass c;
public:
Wrapper() : c(0) {} // correct
Wrapper() { c = NTCClass(0); } // illegal, c is not trivially constructible
};
c = NTCClass(0);
实际上是赋值给已经构造的对象,所以这里已经调用了默认构造函数。(如果类没有默认构造函数,这将失败并产生编译错误)。
是的,这是有区别的。在第一个例子中,firstName
和secondName
在进入构造函数体之前被实例化。一旦它们被实例化,在firstName
上执行赋值,然后在secondName
上执行赋值。在第二个例子中,firstName
和secondName
是通过它们的复制构造函数实例化的,没有额外的赋值。
-
是的,有很大的不同。
-
在第一个版本中,成员变量
firstName
和secondName
将首先被构造(即std::string
的默认构造函数将被分别调用),然后它们的赋值操作符将在class human
的构造函数体中被调用,以便它们分别取fname
和sname
的值。 -
在第二个版本中,成员变量
firstName
和secondName
在创建时被初始化(即,只有它们的构造函数会被调用)。因此,可以避免在构造函数体中重复调用赋值操作符。 -
也就是说,第二个版本更有效,在任何可能的情况下都应该首选。
-
还有一件事要提到的是,您应该通过常量引用而不是通过值传递输入参数
fname
和sname
,以避免为每个参数调用复制构造函数。
因此,这是您应该选择的版本:
human::human(std::string const &fname, std::string const &sname)
: firstName(fname), secondName(sname){}
相关文章:
- 有没有一种代码密度较低的方法来使用非默认构造函数初始化数组?
- 是否可以避免在以下代码中复制/移动构造函数的需要?
- 引入参数化构造函数后显示 LNK 2019 未解析外部符号的代码错误
- 为什么我的代码中没有调用move构造函数
- 基于构造函数的存在禁用代码
- 如何从构造函数返回错误代码?
- 为什么在我的代码中调用复制构造函数而不是移动构造函数?
- 如何基于构造函数参数模板化类成员函数的代码
- C++,处理多个构造函数重载和冗余代码
- 为什么在使用转换构造函数编译代码时需要 const 复制构造函数?
- 该构造函数代码如何将指针作为参数
- 复制赋值和复制构造函数(代码C++的差异)
- 在构造函数代码之前禁用默认类成员初始化
- 以下移动构造函数代码安全吗?
- C++构造函数代码..这叫什么
- 如何更改SWIG生成的CSHARP文件中的构造函数代码
- C++某些构造函数代码之间的区别
- 如何正确编写构造函数代码
- 在全局空间中定义的类的构造函数代码何时运行?
- 从静态构造函数代码调用pthread库时失败