【问题标题】:How to correctly write a constructor code? [duplicate]如何正确编写构造函数代码? [复制]
【发布时间】:2014-07-01 14:43:01
【问题描述】:

例如,我有一个类定义:

#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){}

【问题讨论】:

  • 正确的做法是根本不写。

标签: c++


【解决方案1】:

是的,有区别。想象一下你有一个非平凡可构造的类

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);实际上是赋值给已经构造好的对象,所以这里已经调用了默认构造函数。 (如果类没有默认构造函数,这将失败并出现编译错误)。

【讨论】:

  • 如果你愿意,你也可以提到 const 成员。
  • @sharth 谢谢,这也是一个很好的例子。
【解决方案2】:

是的,有区别。在第一个示例中,firstNamesecondName 在您进入构造函数主体之前被实例化。一旦它们被实例化,就会在firstName 然后secondName 上执行分配。在第二个示例中,firstNamesecondName 通过它们的复制构造函数实例化,无需额外赋值。

【讨论】:

    【解决方案3】:
    • 是的,有很大的不同。

    • 在第一个版本中,成员变量 firstNamesecondName 将首先被构造(即,std::string 的默认构造函数将为它们中的每一个调用),然后对其赋值运算符将在class human 的构造函数主体中被调用,以便它们分别获取fnamesname 的值。

    • 在第二个版本中,成员变量 firstNamesecondName 在创建时被初始化(即,只会调用它们的构造函数)。因此,您可以避免在构造函数主体中对赋值运算符进行冗余调用。

    • 也就是说,第二个版本效率更高,应尽可能首选。

    • 1234563 /p>

    因此,这是您应该喜欢的版本:

    human::human(std::string const &fname, std::string const &sname)
    : firstName(fname), secondName(sname){}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-13
      • 2016-04-09
      • 1970-01-01
      • 2021-04-30
      • 2019-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多