unique_ptr 的开销有多大
unique_ptr 的是零开销的,我们看看具体是指什么含义。
#include <memory>
using namespace std;
struct Foo{
    Foo();
    ~Foo();
};
void UniquePtr() {
    auto p = make_unique<Foo>();
}
void RawPtr() {
    auto p = new Foo();
    delete p;
}
我们编译一下,然后看看生产的汇编指令
+ g++ -Os -fno-exceptions -std=c++14 -c -o unique_ptr_overhead.o unique_ptr_overhead.cpp
+ objdump -D unique_ptr_overhead.o
unique_ptr_overhead.o:	file format Mach-O 64-bit x86-64
Disassembly of section __TEXT,__text:
__Z9UniquePtrv:
       0:	55 	pushq	%rbp
       1:	48 89 e5 	movq	%rsp, %rbp
       4:	53 	pushq	%rbx
       5:	50 	pushq	%rax
       6:	bf 01 00 00 00 	movl	$1, %edi
       b:	e8 00 00 00 00 	callq	0 <__Z9UniquePtrv+0x10>
      10:	48 89 c3 	movq	%rax, %rbx
      13:	48 89 df 	movq	%rbx, %rdi
      16:	e8 00 00 00 00 	callq	0 <__Z9UniquePtrv+0x1b>
      1b:	48 89 df 	movq	%rbx, %rdi
      1e:	e8 00 00 00 00 	callq	0 <__Z9UniquePtrv+0x23>
      23:	48 89 df 	movq	%rbx, %rdi
      26:	48 83 c4 08 	addq	$8, %rsp
      2a:	5b 	popq	%rbx
      2b:	5d 	popq	%rbp
      2c:	e9 00 00 00 00 	jmp	0 <__Z6RawPtrv>
__Z6RawPtrv:
      31:	55 	pushq	%rbp
      32:	48 89 e5 	movq	%rsp, %rbp
      35:	53 	pushq	%rbx
      36:	50 	pushq	%rax
      37:	bf 01 00 00 00 	movl	$1, %edi
      3c:	e8 00 00 00 00 	callq	0 <__Z6RawPtrv+0x10>
      41:	48 89 c3 	movq	%rax, %rbx
      44:	48 89 df 	movq	%rbx, %rdi
      47:	e8 00 00 00 00 	callq	0 <__Z6RawPtrv+0x1b>
      4c:	48 89 df 	movq	%rbx, %rdi
      4f:	e8 00 00 00 00 	callq	0 <__Z6RawPtrv+0x23>
      54:	48 89 df 	movq	%rbx, %rdi
      57:	48 83 c4 08 	addq	$8, %rsp
      5b:	5b 	popq	%rbx
      5c:	5d 	popq	%rbp
      5d:	e9 00 00 00 00 	jmp	0 <__Z6RawPtrv+0x31>
我们大致比较,可以那看到 make_unique 和 new/delete 编译出来了同样的指令,几乎没有区别。
同样,我们也可以看到,在空间占用上,开销也是一样的,因为 sizeof(unique_ptr<Foo>) == sizeof(Foo*)