返回首页

隐了明确的任务分配的优势是什么?
考虑下面的例子:


class base

{

    int b;

public:

    base()

    {

        b = 0;

    }

    base(int x):b(x)

    {

    }

};

int _tmain(int argc, _TCHAR* argv[])

{

    class base bobj(44);

 

    return 0;

}


在通常情况下,我已经看到类变量初始化隐分配为标准数据类型,如上所示。
为什么它是首选呢?

明确所示的分配也做同样的事情:
{C}
那么为什么是隐含了明确的首选?
基地的优势是什么(X):B(X)
基地(X)
{
B = X;
?| rupeshkp728

回答

评论会员:游客 时间:2012/02/07
阅读这,也许这将有助于你imgsrc=]
明可夫斯基:嗨,

我建议你阅读斯科特・迈耶的"有效"和"更有效的C"。你不能称自己一个C程序员,直到你做。他探讨如何写低维护,高品质的代码和definately兼谈您的查询
NBSP以上;
心连心
评论会员:游客 时间:2012/02/07
Stefan_Lang:正确的术语,这里使用的是初始化列表初始化列表。由于可夫斯基已经指出斯科特・迈耶在以前的解决方案,这里是一个线程,在这个主题中引用他的书:{A}]
大卫"地塞米松"施瓦茨:
。对于普通的旧数据(如int)的成员所生成的代码几乎是相同的优势来时,b是不普通的旧数据
在这种情况下。生成的代码将有一个默认的建设,分配,而不是一个明确的建设。在更少的代码,所以成员的初始化
唯一的警告或建议,这种情况下,我可以给你,你应该照顾,以确保成员的初始化不承担施工顺序为成员。rivatnt: |其更有效地使用初始化列表。当你比较POD类型和复杂类型,但仍然使用初始化列表是更优雅,性能上的差异是微不足道的。议员甚至身体构造函数被执行之前被初始化。

有一个初始化列表是强制性的情况下,这样说,当你在你的类常量或引用。

此外,如果你有相同的名称作为数据成员初始化的编译器会知道如何解决这些名字。

A类{
INT A;
市民:
(一):(一){}
};
评论会员:Stefan_Lang 时间:2012/02/07
隐式方法,编译器是免费的自动重新诠释通过隐式构造一个操作数转换为另一种类型的表达式。明确表示这是禁止的。

考虑这些例子:
class Complex {

private:

  double im_;

  double re_;

public:

  Complex(double re) : re_(re) {} // implicit

  Complex(double re, double im) : re_(re), im_(im) {} // not implicit

  explicit Complex(double* vec) { re_ = vec[0]; im_ = vec[1]; } // explicit

  // ...

};

void Foo() {

  Complex ca(1.0), cb(0.0, 1.0);

  double mydouble = 3.14;

  double * ar = &mydouble;

  double va[] = { -1.0, 1.0 };

  Complex cc = ca + Complex(va); // explicit constructor required!

  Complex cd = cc - 3.0; // implicit constructor called

  Complex ce = cb + ar; // error: cannot convert double* to Complex; explicit construction required

}

最后一行将导致一个编译错误,但只是因为我增加了明确的适当的构造。如果我没有,一个简单的类型或其他监督可能让编译器接受这一行,即使它没有太大的意义。在的关键字ecplicit这里帮助我们在编译时的健康检查。
PS:我刚刚注意到你实际上没有谈论隐式和显式的构造,使用明确的关键字,毕竟。我希望我的回答仍然可以棚上有些相关领域的一些轻......
评论会员:Stefan_Lang 时间:2012/02/07
。我只记得初始化列表,这可能会影响代码语义的另一项重要的财产,所以我想我会提到它

考虑下面的代码:
{体C3}调用派生的构造后,出现以下情况:

0。如果没有派生类的其他实例已创建前,虚函数表将在内存中创建
1。内存被分配。
未初始化的内存,甚至可能不被设置为0。2。基地被初始化,因为它是在初始化列表
3。基地::的X_被初始化为1.5,因为它是基地:: Base的初始化列表(双)
4。基地:: Base的代码(双)被执行
5。 MyMgicNumber()被调用,通过vtable的,它得到解决派生:: MyMagicNumber()
6。派生:: MyMagicNumber()读取派生:: I_然后返回I_ 1
7。基地::基地(双)与从MyMagicNumber()初始化基地:: Y_。
构造完成。8。基地与基地::(双),终于没有别的初始化列表,从派生::派生(INT)的代码被执行
派生:: I_被初始化为3
因此,在施工期间发生的最后一件事是初始化派生:: I_,但前一段时间,它已经被阅读!因此,基地:: Y_的状态是不确定的!当然,真正的问题是,你不应该在你的构造函数代码调用虚函数,但您可以修复它​​,很容易把我初始化列表以及:
{的C4}有。这将初始化派生:: I_位置2,现在的下列相应的初始化::,Y_将是良好定义的!

总之,初始化之前调用基类构造函数的类成员初始化列表中是唯一的出路!你需要记住的是初始化顺序:
- 首先,初始化列表,从左至右(这可能包括直接基类)
- 二任何尚未初始化列表中列出的基类的构造函数(不虚基类的要求,我需要看最多)
- 最后在构造体的实际代码