我正在尝试构建一个可以用作某种共享指针的类。出于性能原因,我想实现一个工厂函数,它只需一步就为对象和unsigned int
引用计数器分配内存:
template<typename T> class SharedPointer {
uint8_t* buffer;
T* obj;
unsigned int* counter;
template<typename Args...> static SharedPointer make(Args&&... args) {
SharedPointer p;
p.buffer = new uint8_t[sizeof(T) + sizeof(unsigned int)];
p.obj = new (p.buffer) T(std::forward<Args>(args)...);
p.counter = new (p.buffer + sizeof(T)) unsigned int(1);
return p;
}
}
以后,当共享对象即将被删除时:
~SharedPointer() {
*counter--;
if (*counter == 0) {
obj->~T();
delete[] buffer;
}
}
问题是:是否有必要为分配的缓冲区设置正确的内存对齐方式,如何实现?我知道关键字alignas
,但我不知道应该如何在此处进行整合。
更新 正如评论中指出的那样,可以使用std :: aligned_storage。那么这是一个可能的解决方案:
template<typename T> class SharedPointer {
struct Storage {
std::aligned_storage_t<sizeof(T), alignof(T)> obj;
unsigned int counter;
};
Storage* buffer;
T* obj;
unsigned int* counter;
template<typename Args...> static SharedPointer make(Args&&... args) {
SharedPointer p;
p.buffer = new Storage();
p.obj = new (p.buffer) T(std::forward<Args>(args)...);
p.counter = new (p.buffer + sizeof(T)) unsigned int(1);
return p;
}
~SharedPointer() {
*counter--;
if (*counter == 0) {
obj->~T();
delete buffer;
}
}
}