概述
目录
一、关键点解析
1、__cplusplus
2、c++allocator.h文件内容分析
3、_GLIBCXX_VISIBILITY
4、_GLIBCXX_BEGIN_NAMESPACE_VERSION
二、源码分析
一、关键点解析
1、__cplusplus
这是一个c++预定义宏
c++ 98中,是199711L
c++ 11中,是201103L
2、c++allocator.h文件内容分析
#if __cplusplus >= 201103L
namespace std
{
/**
* @brief An alias to the base class for std::allocator.
* @ingroup allocators
*
* Used to set the std::allocator base class to
* __gnu_cxx::new_allocator.
*
* @tparam _Tp Type of allocated object.
*/
template<typename _Tp>
using __allocator_base = __gnu_cxx::new_allocator<_Tp>;
}
#else
// Define new_allocator as the base class to std::allocator.
# define __allocator_base __gnu_cxx::new_allocator
#endif
#endif
从上述代码可以发现__allocator_base为__gnu_cxx::new_allocator<_Tp>
3、_GLIBCXX_VISIBILITY
It's a preprocessor macro. And is defined as:
// If platform uses neither visibility nor psuedo-visibility,
// specify empty default for namespace annotation macros.
#ifndef _GLIBCXX_PSEUDO_VISIBILITY
# define _GLIBCXX_PSEUDO_VISIBILITY(V)
#endif
#if _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY
#define _GLIBCXX_VISIBILITY(V) __attribute__ ((__visibility__ (#V)))
#else
#define _GLIBCXX_VISIBILITY(V)
#endif
So if _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY
is true then in your case it will expand to:
__attribute__ (( __visibility__ ("default")))
else if _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY
is false it will do nothing.
The __visibility__
attribute is used for defining the visibility of the symbols in a DSO file. Using "hidden" instead of "default" can be used to hide symbols from things outside the DSO.
For example:
__attribute__ ((__visibility__("default"))) void foo();
__attribute__ ((__visibility__("hidden"))) void bar();
The function foo()
would be useable from outside the DSO whereas bar()
is basically private and can only be used inside the DSO.
You can read a bit more about the __visibility__
attribute here: Visibility - GCC Wiki
4、_GLIBCXX_BEGIN_NAMESPACE_VERSION
// Defined if inline namespaces are used for versioning.
# define _GLIBCXX_INLINE_VERSION 0
// Inline namespace for symbol versioning.
#if _GLIBCXX_INLINE_VERSION
namespace std
{
inline namespace __7 { }
namespace rel_ops { inline namespace __7 { } }
namespace tr1
{
inline namespace __7 { }
namespace placeholders { inline namespace __7 { } }
namespace regex_constants { inline namespace __7 { } }
namespace __detail { inline namespace __7 { } }
}
namespace tr2
{ inline namespace __7 { } }
namespace decimal { inline namespace __7 { } }
namespace chrono { inline namespace __7 { } }
namespace placeholders { inline namespace __7 { } }
namespace regex_constants { inline namespace __7 { } }
namespace this_thread { inline namespace __7 { } }
namespace experimental { inline namespace __7 { } }
namespace __detail { inline namespace __7 { } }
}
namespace __gnu_cxx
{
inline namespace __7 { }
namespace __detail { inline namespace __7 { } }
}
# define _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace __7 {
# define _GLIBCXX_END_NAMESPACE_VERSION }
#else
# define _GLIBCXX_BEGIN_NAMESPACE_VERSION
# define _GLIBCXX_END_NAMESPACE_VERSION
#endif
inlinespace是c++11的新特性,示例代码如下:
#include <iostream>
using namespace std;
namespace all
{
//inline作用为默认调用
inline namespace V2022
{
void fun(int num)
{
cout << "int" << "V2017" << endl;
}
}
namespace V2021
{
void fun(int num)
{
cout << "int" << "V2021" << endl;
}
void fun(double num)
{
cout << "double" << "V2021" << endl;
}
}
}
void main()
{
all::fun(1);
all::V2021::fun(1);
cin.get();
}
二、源码分析
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
using std::size_t;
using std::ptrdiff_t;
/**
* @brief An allocator that uses global new, as per [20.4].
* @ingroup allocators
*
* This is precisely the allocator defined in the C++ Standard.
* - all allocation calls operator new
* - all deallocation calls operator delete
*
* @tparam _Tp Type of allocated object.
*/
template<typename _Tp>
class new_allocator
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef _Tp* pointer;
typedef const _Tp* const_pointer;
typedef _Tp& reference;
typedef const _Tp& const_reference;
typedef _Tp value_type;
template<typename _Tp1>
struct rebind
{ typedef new_allocator<_Tp1> other; };
#if __cplusplus >= 201103L
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2103. propagate_on_container_move_assignment
typedef std::true_type propagate_on_container_move_assignment;
#endif
new_allocator() _GLIBCXX_USE_NOEXCEPT { }
new_allocator(const new_allocator&) _GLIBCXX_USE_NOEXCEPT { }
template<typename _Tp1>
new_allocator(const new_allocator<_Tp1>&) _GLIBCXX_USE_NOEXCEPT { }
~new_allocator() _GLIBCXX_USE_NOEXCEPT { }
pointer
address(reference __x) const _GLIBCXX_NOEXCEPT
{ return std::__addressof(__x); }
const_pointer
address(const_reference __x) const _GLIBCXX_NOEXCEPT
{ return std::__addressof(__x); }
// NB: __n is permitted to be 0. The C++ standard says nothing
// about what the return value is when __n == 0.
pointer
allocate(size_type __n, const void* = 0)
{
if (__n > this->max_size())
std::__throw_bad_alloc();
return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));
}
// __p is not permitted to be a null pointer.
void
deallocate(pointer __p, size_type)
{ ::operator delete(__p); }
size_type
max_size() const _GLIBCXX_USE_NOEXCEPT
{ return size_t(-1) / sizeof(_Tp); }
#if __cplusplus >= 201103L
template<typename _Up, typename... _Args>
void
construct(_Up* __p, _Args&&... __args)
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
template<typename _Up>
void
destroy(_Up* __p) { __p->~_Up(); }
#else
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 402. wrong new expression in [some_] allocator::construct
void
construct(pointer __p, const _Tp& __val)
{ ::new((void *)__p) _Tp(__val); }
void
destroy(pointer __p) { __p->~_Tp(); }
#endif
};
template<typename _Tp>
inline bool
operator==(const new_allocator<_Tp>&, const new_allocator<_Tp>&)
{ return true; }
template<typename _Tp>
inline bool
operator!=(const new_allocator<_Tp>&, const new_allocator<_Tp>&)
{ return false; }
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
最后
以上就是无限信封为你收集整理的GNU C++ 智能指针7-- 解析__allocator_base类1一、关键点解析二、源码分析的全部内容,希望文章能够帮你解决GNU C++ 智能指针7-- 解析__allocator_base类1一、关键点解析二、源码分析所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复