story的延续。
考虑安全软件,其中不允许使用碎片进行动态分配。仅当class explicity定义operator delete
和new
以避免碎片时才允许动态分配。
现在,我们有机会针对我们想要获得的任何类优化运算符delete
和template<class T, unsigned size>
class MemoryPool
{
private:
struct Pool
{
bool allocated __attribute__ ((aligned (sizeof(void*))));
uint8_t memory[sizeof(T)] __attribute__ ((aligned (sizeof(void*))));
};
static std::array<uint8_t[sizeof(Pool)], size> memoryPool;
public:
void* operator new(std::size_t) noexcept
{
T* ret = nullptr;
for(auto it = memoryPool.begin(); it != memoryPool.end(); ++it)
{
/* ... */
}
return ret;
}
void operator delete(void* ptr) noexcept
{
for(auto it = memoryPool.begin(); it != memoryPool.end(); ++it)
{
/* ... */
}
}
};
的显式定义。乍一看,任何类都可以继承的模板类是最简单,最清晰的方法,可供最终用户使用。
class Interface
{/*...*/};
class Foo : public Interface, MemoryPool<Foo, 8>
{/*...*/};
class Bar : public Interface
{/*...*/};
如果这是一个童话故事,那么使用MemoryPool宣传课程会很好。
Foo* foo = new Foo(); // goes to dedicated memory pool
Bar* bar = new Bar(); // fails on build
对象声明:
static std::array<uint8_t[sizeof(Pool)], size> memoryPool;
但即使Foo
是静态的并且会超出类,因此它不会改变类的大小,编译器会抱怨Foo
不完整且不能推断出大小src/metal/dynamic.hpp:14:24: error: invalid application of 'sizeof' to incomplete type 'Foo'
uint8_t memory[sizeof(T)] __attribute__ ((aligned (sizeof(void*))));
{{1}}
是否可以解决此“不完整类型”错误?
或者我应该完全重新设计解决方案?
答案 0 :(得分:2)
问题是Foo
在实例化MemoryPool
时还不是一个完整的类型。
main.cpp:10:24: error: invalid application of 'sizeof' to an incomplete type 'Foo'
uint8_t memory[sizeof(T)] __attribute__ ((aligned (sizeof(void*))));
^~~~~~~~~
main.cpp:13:31: note: in instantiation of member class 'MemoryPool<Foo, 8>::Pool' requested here
static std::array<uint8_t[sizeof(Pool)], size> memoryPool;
^
main.cpp:35:20: note: in instantiation of template class 'MemoryPool<Foo, 8>' requested here
class Foo : public MemoryPool<Foo, 8>
^
main.cpp:35:7: note: definition of 'Foo' is not complete until the closing '}'
class Foo : public MemoryPool<Foo, 8>
^
您可以通过延迟应用sizeof
来解决此问题,直到Foo
为完整类型。
这可以通过静态成员函数访问memoryPool
来完成:
template<class T, unsigned size>
class MemoryPool
{
private:
struct Pool
{
bool allocated __attribute__ ((aligned (sizeof(void*))));
uint8_t memory[sizeof(T)] __attribute__ ((aligned (sizeof(void*))));
};
template <typename P>
static std::array<uint8_t[sizeof(P)], size>& getPool()
{
static std::array<uint8_t[sizeof(P)], size> memoryPool;
return memoryPool;
}
public:
void* operator new(std::size_t) noexcept
{
T* ret = nullptr;
for(auto it = getPool<Pool>().begin(); it != getPool<Pool>().end(); ++it)
{
/* ... */
}
return ret;
}
};
<强> live example 强>
C ++ 14允许稍微简单的实现:
template<class T, unsigned size>
class MemoryPool
{
private:
struct Pool
{
bool allocated __attribute__ ((aligned (sizeof(void*))));
uint8_t memory[sizeof(T)] __attribute__ ((aligned (sizeof(void*))));
};
static auto& getPool()
{
static std::array<uint8_t[sizeof(Pool)], size> memoryPool;
return memoryPool;
}
public:
void* operator new(std::size_t) noexcept
{
T* ret = nullptr;
for(auto it = getPool().begin(); it != getPool().end(); ++it)
{
/* ... */
}
return ret;
}
};
<强> live example 强>