对于类构造函数,通过括号或等号的赋值之间的区别是什么? [英] For a class constructor, what is the difference between the assignment via parentheses or the equal sign?

查看:866
本文介绍了对于类构造函数,通过括号或等号的赋值之间的区别是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


可能重复:

在构造函数 - 初始化器列表与构造函数主体中初始化字段


在我参加的讲座中,讲师在C ++中简要讨论了非默认类构造函数。他特别指出,一个版本比另一个更好。他显示了这两个例子:

  Point :: Point(double x,double y,double z)
:x_ (x),y​​_(y),z_(z)
{}

Point :: Point(double x,double y,double z)
{x_ = x; y_ = y; z_ = z; }



他提到第一个例子(使用括号)是编写构造函数的首选方法。 / p>

我的问题是:有什么区别,为什么很重要?原因是第一个是不是 >一个赋值,它是一个初始化,第二个代码实际上是这样的:

  double y,double z)
:x_(),y_(),z_()
{x_ = x; y_ = y; z_ = z; }

也就是说,所有成员在分配之前都是默认初始化。这不工作,当他们的类型没有默认构造函数。例如:

  class Foo {
Foo // Private,undefined constructor
public:
Foo(int){}
};

class Bar {
int&一世;
Foo f;

public:
Bar(){i = 0; f = Foo(0); }
};

此代码将无法工作,因为 Bar 的构造函数依赖于 f 的默认构造函数以及 i 的初始化程序的存在,两者都不存在。



但即使所有成员都是默认可构造的或初始化的,仍然建议在初始化列表中初始化它们,而不是通过构造函数中的赋值:它更高效(因为否则你将执行冗余操作,在某些情况下可能是昂贵的)。


Possible Duplicate:
Initializing fields in constructor - initializer list vs constructor body

In a lecture I attended, the lecturer talked briefly in C++ about non-default class constructors. He stated specifically that one version was preferable to the other. He showed these two examples:

Point::Point(double x, double y, double z)
: x_(x), y_(y), z_(z)
{}

Point::Point(double x, double y, double z)
{ x_= x; y_= y; z_= z; }

He mentioned that the first example (using parentheses) was the preferred way to write the constructor.

My question is: What's the difference and why does it matter? In what way is the first superior to the second?

解决方案

The reason is that the first is not an assignment, it’s an initialisation, and the second code is actually identical to this:

Point::Point(double x, double y, double z)
: x_(), y_(), z_()
{ x_= x; y_= y; z_= z; }

That is, all members are default-initialised here before being assigned. That doesn’t work when their types have no default constructor. For instance:

class Foo {
    Foo(); // Private, undefined constructor
public:
    Foo(int) { }
};

class Bar {
    int& i;
    Foo f;

public:
    Bar() { i = 0; f = Foo(0); }
};

This code won’t work because Bar’s constructor relies on the existence of a default constructor for f and an initialiser for i, neither of which exists.

But even if all members are default-constructible or initialisable, it is still advisable to initialise them in the initialisation list rather than via assignment in the constructor: if nothing else, it’s more efficient (because otherwise you’ll perform redundant operations which may be costly in some cases).

这篇关于对于类构造函数,通过括号或等号的赋值之间的区别是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆