c++ - 两者中哪一个会更快地初始化对象?

标签 c++

class A {
   public:
   int a;
   A(int x)
   {
      a = x;
   }
};

class B {
       public:
       int b;
       B(int x):b(x){}
};

哪个会更快地初始化对象?或者最终会为两者生成相同的代码并且初始化所花费的时间将保持不变?还是取决于编译器?

最佳答案

对于 POD 成员,包括 int,它们将是相同的,因为该成员不会被构造两次。

对于具有默认构造函数的类型,第二个会更快,因为第一个选项等同于:

A(B x) : a()
{
   a = x;
}

如果 a 是类型 B 的成员(具有默认构造函数)。

请注意,在某些情况下您必须使用初始化列表:const 成员、引用成员、没有默认构造函数的类类型的成员。

POD 成员:

没有初始化列表:

   A(int x)
001F1430  push        ebp  
001F1431  mov         ebp,esp  
001F1433  sub         esp,0CCh  
001F1439  push        ebx  
001F143A  push        esi  
001F143B  push        edi  
001F143C  push        ecx  
001F143D  lea         edi,[ebp-0CCh]  
001F1443  mov         ecx,33h  
001F1448  mov         eax,0CCCCCCCCh  
001F144D  rep stos    dword ptr es:[edi]  
001F144F  pop         ecx  
001F1450  mov         dword ptr [ebp-8],ecx  
   {
      a = x;
001F1453  mov         eax,dword ptr [this]  
001F1456  mov         ecx,dword ptr [x]  
001F1459  mov         dword ptr [eax],ecx  
   }

初始化列表:

   A(int x) : a(x)
00E71430  push        ebp  
00E71431  mov         ebp,esp  
00E71433  sub         esp,0CCh  
00E71439  push        ebx  
00E7143A  push        esi  
00E7143B  push        edi  
00E7143C  push        ecx  
00E7143D  lea         edi,[ebp-0CCh]  
00E71443  mov         ecx,33h  
00E71448  mov         eax,0CCCCCCCCh  
00E7144D  rep stos    dword ptr es:[edi]  
00E7144F  pop         ecx  
00E71450  mov         dword ptr [ebp-8],ecx  
00E71453  mov         eax,dword ptr [this]  
00E71456  mov         ecx,dword ptr [x]  
00E71459  mov         dword ptr [eax],ecx  

即相同,那是因为 a 在进入构造函数主体之前未被初始化。

非 POD 成员(member):

没有初始化列表:

00EB1A80  push        ebp  
00EB1A81  mov         ebp,esp  
00EB1A83  sub         esp,0CCh  
00EB1A89  push        ebx  
00EB1A8A  push        esi  
00EB1A8B  push        edi  
00EB1A8C  push        ecx  
00EB1A8D  lea         edi,[ebp-0CCh]  
00EB1A93  mov         ecx,33h  
00EB1A98  mov         eax,0CCCCCCCCh  
00EB1A9D  rep stos    dword ptr es:[edi]  
00EB1A9F  pop         ecx  
00EB1AA0  mov         dword ptr [ebp-8],ecx  
00EB1AA3  mov         ecx,dword ptr [this]  
00EB1AA6  call        B::B (0EB11D6h)  
   {
       a = b;
   }
00EB1AAB  mov         eax,dword ptr [this]  
00EB1AAE  pop         edi  
00EB1AAF  pop         esi  
00EB1AB0  pop         ebx  
00EB1AB1  add         esp,0CCh  
00EB1AB7  cmp         ebp,esp  
00EB1AB9  call        @ILT+315(__RTC_CheckEsp) (0EB1140h)  
00EB1ABE  mov         esp,ebp  
00EB1AC0  pop         ebp  
00EB1AC1  ret         4  

初始化器列表:

A(B b) : a(b)
   {
00841650  push        ebp  
00841651  mov         ebp,esp  
00841653  sub         esp,0CCh  
00841659  push        ebx  
0084165A  push        esi  
0084165B  push        edi  
0084165C  push        ecx  
0084165D  lea         edi,[ebp-0CCh]  
00841663  mov         ecx,33h  
00841668  mov         eax,0CCCCCCCCh  
0084166D  rep stos    dword ptr es:[edi]  
0084166F  pop         ecx  
00841670  mov         dword ptr [ebp-8],ecx  
   }

即初始化列表选项更好。

关于c++ - 两者中哪一个会更快地初始化对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12663329/

相关文章:

c++ - 如何自动推断结构模板中 C 数组的大小?

c++ - 绑定(bind)成员函数的指针/引用的禁止语法

c++ - 在 c++ lambda 中更改捕获变量的值

c++ - 对于 C++ 中的多个数组,for 循环不能正常工作

C++ 预处理器路径根

c++ - 是否可以将用户输入的单词存储为字符数组?

c++ - ffmpeg AVFrame 获取完整的解码数据到 char*

c++ - 在 VC++ 中使用单独的库进行调试和发布

c++ - 通过循环创建弹出菜单 w.r.t 到参数时的问题

c++ - 如何使用 std::mt19937 避免相同的随机结果?