那是你见识太少了。问你两个问题,不求你能回答,但至少求你能看的懂问题。
1. SIMD 中不少指令是要求数据对齐的,请问要是对齐要求超过了 malloc/new 默认的对齐了,你打算怎么办?
对齐版本的 operator new 重载了解一下?
void
*
operator
new
(
std
::
size_t
count
,
std
::
align_val_t
al
);
2. new 申请不到内存时,在默认情况下,是会一个循环,不断调用 std::get_new_handler 返回的函数指针,直到分配成功为止的。我觉得这也太坑了,顶多试三次就行了,你打算怎么办?
把你代码里出现 new 的地方全一个一个替换掉么?累死你。
你说用不到这个功能,那是因为都给你封装在底层了,不需要来让你操心了。
我跟你说,要是没重载 new 这个功能,你连最基础的 vector 都实现不了。
vector 最核心的需求是什么?是要求内存分配和对象的构造之间能解耦、解分配和对象的析构之间能解耦。说人话,就是需要先用 allocator.allocate() 方法从分配器中提前分配出内存块, 等推迟到合适的时候,才在这个内存块上构造出对象 。
那些叫嚣 100 行写出的 vector,其实现都是根本不能用的,里面全是用的 new T[]。
正规的写法必须要用到 placement new —— 这是重载 new 的最机智的利用。
vector 的基本原理如下:
#include
<new>
#include
<iostream>
struct
Foo
{
int
i
;
Foo
(
int
i
)
:
i
(
i
)
{
std
::
cout
<<
"构造 "
<<
i
<<
std
::
endl
;
}
~
Foo
()
{
std
::
cout
<<
"析构 "
<<
i
<<
std
::
endl
;
}
};
int
main
()
{
std
::
allocator
<
Foo
>
alloc
;
Foo
*
p
=
alloc
.
allocate
(
3
);
std
::
cout
<<
"分配好缓冲区了"
<<
std
::
endl
;
for
(
int
i
=
0
;
i
<
3
;
++
i
)
{
std
::
cout
<<
"push_back 第 "
<<
i
<<
" 个元素"
<<
std
::
endl
;
new
(
p
+
i
)
Foo
(
i
);
}
for
(
int
i
=
0
;
i
<
3
;
++
i
)
{
std
::
cout
<<
"pop_back 第 "
<<
i
<<
" 个元素"
<<
std
::
endl
;
(
p
+
2
-
i
)
->~
Foo
();
}
alloc
.
deallocate
(
p
,
3
);
std
::
cout
<<
"释放完缓冲区了"
<<
std
::
endl
;
}
输出:
分配好缓冲区了
push_back 第 0 个元素
构造 0
push_back 第 1 个元素
构造 1
push_back 第 2 个元素
构造 2
pop_back 第 0 个元素
析构 2
pop_back 第 1 个元素
析构 1
pop_back 第 2 个元素
析构 0
释放完缓冲区了
你以为 placement new 是 C++ 为其特殊设计的语法?
不是的,placement new 只是一个函数调用而已。它只不过是:
void
*
operator
new
(
std
::
size_t
,
void
*
p
)
{
return
p
;
}