As @milleniumbug said, std::unique_ptr
use Empty Base Optimization
. It means you can declare a class with no data member:
class empty
{
public:
// methods
};
If you have another class that declare a member variable of empty
inside it, the size of your class will increase even if empty
has no data member:
class foo
{
public:
int i;
empty em;
};
In this case size of foo
will be 8 byte. But if you declare foo
to inherit from empty
, this inheritance has no effect in size of foo
and it's size will be 4 byte:
class foo : public empty
{
public:
int i;
};
If you take a look into std::unique_ptr
implementation of your compiler you will see this. I'm using VC++ 2015 and in this compiler structure of std::unique_ptr
is like below:
template<class _Ty, class _Dx> // = default_delete<_Ty>
class unique_ptr : public _Unique_ptr_base<_Ty, _Dx>
It inherit from this class:
template<class _Ty, class _Dx>
class _Unique_ptr_base
{ // stores pointer and deleter
public:
...
_Compressed_pair<_Dx, pointer> _Mypair;
};
In _Unique_ptr_base
there is a member of type _Compressed_pair
. This class is declared in this way:
template<class _Ty1, class _Ty2, bool = is_empty<_Ty1>::value && !is_final<_Ty1>::value>
class _Compressed_pair final
: private _Ty1
{ // store a pair of values, deriving from empty first
private:
_Ty2 _Myval2;
Actually this class is specialized if it's second template argument is an empty class. In this case it inherit from empty deleter class and declare a member variable of first template argument that is std::unique_ptr
pointer.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…