c++ - 成员初始化列表,无参数指针初始化

标签 c++ pointers initializer-list

在以前使用很多智能指针现在使用原始指针的大型框架中,我经常遇到这样的情况:

class A {
public:
        int* m;
        A() : m() {}
};

原因是因为 int* m 曾经是一个智能指针,所以初始化列表调用了默认构造函数。现在 int* m 是一个原始指针,我不确定这是否等同于:

class A {
public:
        int* m;
        A() : m(nullptr) {}
};

没有显式的 nullptr A::m 是否仍然初始化为零?看一下没有优化 objdump -d 似乎是肯定的,但我不确定。我认为答案是肯定的原因是 objdump -d 中的这一行(我在下面发布了更多的 objdump -d):

  400644:       48 c7 00 00 00 00 00    movq   $0x0,(%rax)

试图寻找未定义行为的小程序:

class A {
public:
        int* m;
        A() : m(nullptr) {}
};

int main() {
        A buf[1000000];
        unsigned int count = 0;
        for (unsigned int i = 0; i < 1000000; ++i) {
                count += buf[i].m ? 1 : 0;
        }
        return count;
}

编译、执行、返回值:

g++ -std=c++14 -O0 foo.cpp
./a.out; echo $?
0

objdump -d 中的相关汇编部分:

00000000004005b8 <main>:
  4005b8:       55                      push   %rbp
  4005b9:       48 89 e5                mov    %rsp,%rbp
  4005bc:       41 54                   push   %r12
  4005be:       53                      push   %rbx
  4005bf:       48 81 ec 10 12 7a 00    sub    $0x7a1210,%rsp
  4005c6:       48 8d 85 e0 ed 85 ff    lea    -0x7a1220(%rbp),%rax
  4005cd:       bb 3f 42 0f 00          mov    $0xf423f,%ebx
  4005d2:       49 89 c4                mov    %rax,%r12
  4005d5:       eb 10                   jmp    4005e7 <main+0x2f>
  4005d7:       4c 89 e7                mov    %r12,%rdi
  4005da:       e8 59 00 00 00          callq  400638 <_ZN1AC1Ev>
  4005df:       49 83 c4 08             add    $0x8,%r12
  4005e3:       48 83 eb 01             sub    $0x1,%rbx
  4005e7:       48 83 fb ff             cmp    $0xffffffffffffffff,%rbx
  4005eb:       75 ea                   jne    4005d7 <main+0x1f>
  4005ed:       c7 45 ec 00 00 00 00    movl   $0x0,-0x14(%rbp)
  4005f4:       c7 45 e8 00 00 00 00    movl   $0x0,-0x18(%rbp)
  4005fb:       eb 23                   jmp    400620 <main+0x68>
  4005fd:       8b 45 e8                mov    -0x18(%rbp),%eax
  400600:       48 8b 84 c5 e0 ed 85    mov    -0x7a1220(%rbp,%rax,8),%rax
  400607:       ff
  400608:       48 85 c0                test   %rax,%rax
  40060b:       74 07                   je     400614 <main+0x5c>
  40060d:       b8 01 00 00 00          mov    $0x1,%eax
  400612:       eb 05                   jmp    400619 <main+0x61>
  400614:       b8 00 00 00 00          mov    $0x0,%eax
  400619:       01 45 ec                add    %eax,-0x14(%rbp)
  40061c:       83 45 e8 01             addl   $0x1,-0x18(%rbp)
  400620:       81 7d e8 3f 42 0f 00    cmpl   $0xf423f,-0x18(%rbp)
  400627:       76 d4                   jbe    4005fd <main+0x45>
  400629:       8b 45 ec                mov    -0x14(%rbp),%eax
  40062c:       48 81 c4 10 12 7a 00    add    $0x7a1210,%rsp
  400633:       5b                      pop    %rbx
  400634:       41 5c                   pop    %r12
  400636:       5d                      pop    %rbp
  400637:       c3                      retq

0000000000400638 <_ZN1AC1Ev>:
  400638:       55                      push   %rbp
  400639:       48 89 e5                mov    %rsp,%rbp
  40063c:       48 89 7d f8             mov    %rdi,-0x8(%rbp)
  400640:       48 8b 45 f8             mov    -0x8(%rbp),%rax
  400644:       48 c7 00 00 00 00 00    movq   $0x0,(%rax)
  40064b:       5d                      pop    %rbp
  40064c:       c3                      retq
  40064d:       0f 1f 00                nopl   (%rax)

最佳答案

Empty () 初始化器在 C++98 中代表默认初始化,在 C++03 及更高版本中代表值初始化 .对于标量类型(包括指针),值初始化/默认初始化导致零初始化

这意味着在您的情况下 m()m(nullptr) 将具有完全相同的效果:在这两种情况下 m 是初始化为空指针。在 C++ 中,从标准化时代开始就是这样。

关于c++ - 成员初始化列表,无参数指针初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35072499/

相关文章:

c++ - 多态性和指针数组 (C++)

java - 如何使用 JNA Pointer 将数据写入内存?

c++ - 使用 std::initializer_list 构造函数而不产生歧义?

c++ - 如何确定是否可以从给定的初始化列表构造结构?

c++ - 我可以通过类型特征来确定指针是否为整数类型吗?

c++ - header : no such file or directory

iphone - OpenCV 人脸检测 - vector 问题

c - 为什么 Strcpy 函数不能与指向数组的指针一起使用?

c++ - 如何在 C++ 宏中定义模式?

c++ - 使用带有 bitset 的 initializer_list