结论

new() 调用无参的构造函数new 调用默认构造函数/唯一构造函数

  • 对于 构造函数的类,newnew() 都调用构造函数进行初始化;
  • 对于 没有 构造函数的类,则 new 只分配内存空间,不初始化;new() 分配内存空间且初始化。

测试

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <iostream>

void testArray();
void testClass();

int main(int argc, const char * argv[]) {

    // 测试数组
    testArray();
    // 测试类
    testClass();
    
    return 0;
}

// 以这种方式可以发现 new 和 new ()的不同
void testArray() {
    
    // 先初始化一个数组,给每个下标赋值,后面再使用时 new 和 new () 会有不同
    int *pAA = new int[100];
    for (int i = 0; i < 100; ++i) {
        pAA[i] = i;
    }
    delete[] pAA;
    std::cout << std::endl;
    
    
    int *pBB = new int[100]; // 不加()
    for (int i = 0; i < 100; ++i)
    {
        std::cout << pBB[i] << " "; // 会出现随机值
    }
    delete[] pBB;
    std::cout << std::endl; // 换行
    
    
    int *pCC = new int[100](); // 加了()
    for (int i = 0; i < 100; ++i)
    {
        std::cout << pCC[i] << " "; // 都是0
    }
    delete[] pCC;
    std::cout << std::endl;
}

class A
{
public:
    int a;
};

void testClass() {
    A *pp = new A;
    pp->a = 11;
    delete pp;
    
    A *pA1 = new A; // a可能会是随机值
    std::cout << pA1->a << std::endl; // 11
    
    A *pA2 = new A(); // n的值是0
    std::cout << pA2->a << std::endl; // 0
    
}

验证

无论是 new 还是 new A() 从汇编看都调用了 operator new(unsigned long) 从堆中分配内存空间;
但是 new() 后面还调用了 memset 函数来初始化内存,而 new 没有.

new A 和 new A()对应的汇编

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
/** 
    ...
->  0x1000031ab <+59>:  movl   $0x4, %edi
    0x1000031b0 <+64>:  callq  0x100003df6               ; symbol stub for: operator new(unsigned long)
    ...
    0x1000031da <+106>: movl   $0x4, %edi
    0x1000031df <+111>: callq  0x100003df6               ; symbol stub for: operator new(unsigned long)
    0x1000031e4 <+116>: movq   %rax, %rdi
    0x1000031e7 <+119>: xorl   %esi, %esi
    0x1000031e9 <+121>: movq   %rdi, -0x28(%rbp)
    0x1000031ed <+125>: movl   $0x4, %edx
    0x1000031f2 <+130>: callq  0x100003e08               ; symbol stub for: memset
    ...
 */