构造函数初始化 Vs 赋值

新手上路,请多包涵

让我们考虑以下类

class test1
{
    private:
        int a;
        int b;
    public:
        test1():a(0),b(0){}
};

class test2
{
    private:
        int a;
        int b;
    public:
        test2()
        {
            a=0;
            b=0;
        }
};

现在,我知道 test1() 构造函数是初始化 class 的数据成员的正确方法,因为在 test2() 我们正在执行赋值而不是初始化。我的问题是:

  1. 如果我们执行赋值而不是初始化,可能会出现什么问题?
  2. test1() 构造函数的情况下,编译器不会在内部执行赋值吗?如果没有,那么这些是如何初始化的?

原文由 Uttam Malakar 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 387
2 个回答

如果我们执行赋值而不是初始化,可能会出现什么问题?

无法分配某些类类型(以及引用和 const 对象);有些不能默认初始化;有些默认初始化和重新分配可能比直接初始化更昂贵。

在 test1() 构造函数的情况下,编译器不会在内部执行赋值吗?如果没有,那么这些是如何初始化的?

对于像 int 这样的原始类型,两者之间几乎没有实际区别。默认初始化什么都不做,直接初始化和赋值都做同样的事情。

在类类型的情况下,默认初始化、赋值和直接初始化各自调用不同的用户自定义函数,有些操作可能根本不存在;所以总的来说,这两个例子可能有非常不同的行为。

原文由 Mike Seymour 发布,翻译遵循 CC BY-SA 3.0 许可协议

对于您的示例,没有真正的不同,因为您正在初始化纯整数。

但是假设这些整数是具有构造函数的对象,那么编译器将生成以下调用:

 // test1
a::copy_constructor(0);
b::copy_constructor(0);

// test2
a::default_constructor();
b::default_constructor();
a::operator = (0);
b::operator = (0);

因此,根据您的对象 test2 可能会对性能产生巨大影响。此外,通过在初始化列表中初始化您的对象,可以保证您的变量在您进入构造函数时具有数据。初始化器列表的一个“缺点”是它是按照声明变量的顺序执行的,而不是按照初始化器列表的顺序执行的,因此您可能不想使用初始化器列表。

原文由 ConfusedSushi 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题