【问题标题】:Using = for constructing new variable使用 = 构造新变量
【发布时间】:2014-02-06 01:08:21
【问题描述】:

我对使用= 初始化新变量持谨慎态度:

MyClass my_var = MyClass(some_data);
  1. 因为我认为这需要先默认构造 my_var,然后再分配。
  2. my_var 是共享内存时,这可能会导致竞争条件。

有人可以证实或否认我的恐惧吗?原始类型的处理方式不同吗?

【问题讨论】:

标签: c++ constructor initialization variable-assignment default-constructor


【解决方案1】:

因为我认为这需要首先默认构造 my_var,然后再分配。

没有。在类类型的变量声明上使用= 运算符具有特殊处理。编译器永远不会像您想象的那样默认构造然后复制变量对象。实际上会发生的是:

  1. 一个临时的MyClass对象将从some_data复制构造,然后my_var将从临时复制构造,然后临时将被释放。好像你写过这个:

    MyClass my_var(MyClass(some_data));
    
  2. 编译器将完全优化 temp 并直接从 some_data 复制构造 my_var。好像你写过这个:

    MyClass my_var(some_data);
    

    这是通常的情况,特别是如果你这样写:

    MyClass my_var = some_data;
    

    而不是这个:

    MyClass my_var = MyClass(some_data);
    

当 my_var 是共享内存时,这可能会导致竞争条件。

你写它的方式,不。 my_var 要么是函数/方法的局部变量,要么是全局变量。无论哪种方式,在同一语句中声明和分配变量都不是竞争条件,因为在构造变量之前不能共享该变量。如果您先声明变量并在单独的语句中分配它,则会出现竞争条件。

【讨论】:

  • 如果my_var 是一个函数局部静态变量呢?
  • 函数局部静态仅在函数第一次被调用时初始化一次。只有当多个线程同时调用该函数时才会出现竞争条件。但是一旦它被构造出来,构造中就没有竞争条件了,只是在访问时(如果对象内部的逻辑不是线程安全的)。
  • 因此,如果两个不同的线程同时“第一次”调用该函数,存在竞争条件。
  • 这就是我所说的,是的。
【解决方案2】:

在您的代码行中,仅调用了 MyClass 的复制构造函数。

如果您在代码my_var = some_data 中编写了MyClass my_var 和后面的代码,那么将调用MyClass::operator=(...)

为了完成这个答案,我看不出共享变量在构造过程中如何“面临竞争条件的风险”(因为它在构造之前无法共享)。

【讨论】:

    【解决方案3】:

    因为我认为这需要首先默认构造 my_var,然后再分配。

    没有。 my_var 绝不是默认构造的,也不是临时构造的。首先使用some_data 构造一个MyClass 类型的右值,然后调用复制构造函数(如果您在C++11 中,则调用移动构造函数)构造my_var

    当 my_var 是共享内存时,这可能会导致竞争条件。

    嗯,是的。理论上它可能会导致竞争条件。

    【讨论】:

      猜你喜欢
      • 2015-12-14
      • 1970-01-01
      • 2021-01-16
      • 1970-01-01
      • 1970-01-01
      • 2019-09-30
      • 1970-01-01
      • 2023-03-24
      • 2019-02-22
      相关资源
      最近更新 更多