linux gcc 下 没有c++11 时的智能指针实现 参考POCO
AtomicCounter.h 线程安全的原子引用计数 实现
//
// AtomicCounter.h
//
// Library: Foundation
// Package: Core
// Module: AtomicCounter
//
// Definition of the AtomicCounter class.
//
// Copyright (c) 2009, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_AtomicCounter_INCLUDED
#define Foundation_AtomicCounter_INCLUDED
namespace Poco {
class AtomicCounter
/// This class implements a simple counter, which
/// provides atomic operations that are safe to
/// use in a multithreaded environment.
///
/// Typical usage of AtomicCounter is for implementing
/// reference counting and similar things.
///
/// On some platforms, the implementation of AtomicCounter
/// is based on atomic primitives specific to the platform
/// (such as InterlockedIncrement, etc. on Windows), and
/// thus very efficient. On platforms that do not support
/// atomic primitives, operations are guarded by a FastMutex.
///
/// The following platforms currently have atomic
/// primitives:
/// - Windows
/// - Mac OS X
/// - GCC 4.1+ (Intel platforms only)
{
public:
typedef int ValueType; /// The underlying integer type.
AtomicCounter();
/// Creates a new AtomicCounter and initializes it to zero.
explicit AtomicCounter(ValueType initialValue);
/// Creates a new AtomicCounter and initializes it with
/// the given value.
AtomicCounter(const AtomicCounter &counter);
/// Creates the counter by copying another one.
~AtomicCounter();
/// Destroys the AtomicCounter.
AtomicCounter &operator=(const AtomicCounter &counter);
/// Assigns the value of another AtomicCounter.
AtomicCounter &operator=(ValueType value);
/// Assigns a value to the counter.
operator ValueType() const;
/// Returns the value of the counter.
ValueType value() const;
/// Returns the value of the counter.
ValueType operator++(); // prefix
/// Increments the counter and returns the result.
ValueType
operator++(int); // postfix
/// Increments the counter and returns the previous value.
ValueType operator--(); // prefix
/// Decrements the counter and returns the result.
ValueType
operator--(int); // postfix
/// Decrements the counter and returns the previous value.
bool operator!() const;
/// Returns true if the counter is zero, false otherwise.
private:
typedef int ImplType;
ImplType _counter;
};
AtomicCounter::AtomicCounter() : _counter(0) {}
AtomicCounter::AtomicCounter(AtomicCounter::ValueType initialValue)
: _counter(initialValue) {}
AtomicCounter::AtomicCounter(const AtomicCounter &counter)
: _counter(counter.value()) {}
AtomicCounter::~AtomicCounter() {}
//
// GCC 4.1+ atomic builtins.
//
inline AtomicCounter::operator AtomicCounter::ValueType() const {
return _counter;
}
inline AtomicCounter::ValueType AtomicCounter::value() const {
return _counter;
}
inline AtomicCounter::ValueType AtomicCounter::operator++() // prefix
{
return __sync_add_and_fetch(&_counter, 1);
}
inline AtomicCounter::ValueType AtomicCounter::operator++(int) // postfix
{
return __sync_fetch_and_add(&_counter, 1);
}
inline AtomicCounter::ValueType AtomicCounter::operator--() // prefix
{
return __sync_sub_and_fetch(&_counter, 1);
}
inline AtomicCounter::ValueType AtomicCounter::operator--(int) // postfix
{
return __sync_fetch_and_sub(&_counter, 1);
}
inline bool AtomicCounter::operator!() const { return _counter == 0; }
} // namespace Poco
#endif // Foundation_AtomicCounter_INCLUDED
SharedPtr 智能指针的实现
//
// SharedPtr.h
//
// Library: Foundation
// Package: Core
// Module: SharedPtr
//
// Definition of the SharedPtr template class.
//
// Copyright (c) 2005-2008, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_SharedPtr_INCLUDED
#define Foundation_SharedPtr_INCLUDED
#include "AtomicCounter.h"
#include <algorithm>
#include <cassert>
#include <exception>
#include <stdexcept>
namespace Poco {
class ReferenceCounter
/// Simple ReferenceCounter object, does not delete itself when count reaches 0.
{
public:
ReferenceCounter() : _cnt(1) {}
void duplicate() { ++_cnt; }
int release() { return --_cnt; }
int referenceCount() const { return _cnt.value(); }
private:
AtomicCounter _cnt;
};
template <class C>
class ReleasePolicy
/// The default release policy for SharedPtr, which
/// simply uses the delete operator to delete an object.
{
public:
static void release(C *pObj)
/// Delete the object.
/// Note that pObj can be 0.
{
delete pObj;
}
};
template <class C>
class ReleaseArrayPolicy
/// The release policy for SharedPtr holding arrays.
{
public:
static void release(C *pObj)
/// Delete the object.
/// Note that pObj can be 0.
{
delete[] pObj;
}
};
template <class C, class RC = ReferenceCounter, class RP = ReleasePolicy<C> >
class SharedPtr
/// SharedPtr is a "smart" pointer for classes implementing
/// reference counting based garbage collection.
/// SharedPtr is thus similar to AutoPtr. Unlike the
/// AutoPtr template, which can only be used with
/// classes that support reference counting, SharedPtr
/// can be used with any class. For this to work, a
/// SharedPtr manages a reference count for the object
/// it manages.
///
/// SharedPtr works in the following way:
/// If an SharedPtr is assigned an ordinary pointer to
/// an object (via the constructor or the assignment operator),
/// it takes ownership of the object and the object's reference
/// count is initialized to one.
/// If the SharedPtr is assigned another SharedPtr, the
/// object's reference count is incremented by one.
/// The destructor of SharedPtr decrements the object's
/// reference count by one and deletes the object if the
/// reference count reaches zero.
/// SharedPtr supports dereferencing with both the ->
/// and the * operator. An attempt to dereference a null
/// SharedPtr results in a NullPointerException being thrown.
/// SharedPtr also implements all relational operators and
/// a cast operator in case dynamic casting of the encapsulated data types
/// is required.
{
public:
SharedPtr() : _pCounter(new RC), _ptr(0) {}
SharedPtr(C *ptr) try : _pCounter(new RC), _ptr(ptr) {
} catch (...) {
RP::release(ptr);
}
template <class Other, class OtherRP>
SharedPtr(const SharedPtr<Other, RC, OtherRP> &ptr)
: _pCounter(ptr._pCounter), _ptr(const_cast<Other *>(ptr.get())) {
_pCounter->duplicate();
}
SharedPtr(const SharedPtr &ptr) : _pCounter(ptr._pCounter), _ptr(ptr._ptr) {
_pCounter->duplicate();
}
~SharedPtr() {
try {
release();
} catch (...) {
assert(0);
}
}
SharedPtr &assign(C *ptr) {
if (get() != ptr) {
SharedPtr tmp(ptr);
swap(tmp);
}
return *this;
}
SharedPtr &assign(const SharedPtr &ptr) {
if (&ptr != this) {
SharedPtr tmp(ptr);
swap(tmp);
}
return *this;
}
template <class Other, class OtherRP>
SharedPtr &assign(const SharedPtr<Other, RC, OtherRP> &ptr) {
if (ptr.get() != _ptr) {
SharedPtr tmp(ptr);
swap(tmp);
}
return *this;
}
SharedPtr &operator=(C *ptr) { return assign(ptr); }
SharedPtr &operator=(const SharedPtr &ptr) { return assign(ptr); }
template <class Other, class OtherRP>
SharedPtr &operator=(const SharedPtr<Other, RC, OtherRP> &ptr) {
return assign<Other>(ptr);
}
void swap(SharedPtr &ptr) {
std::swap(_ptr, ptr._ptr);
std::swap(_pCounter, ptr._pCounter);
}
template <class Other>
SharedPtr<Other, RC, RP> cast() const
/// Casts the SharedPtr via a dynamic cast to the given type.
/// Returns an SharedPtr containing NULL if the cast fails.
/// Example: (assume class Sub: public Super)
/// SharedPtr<Super> super(new Sub());
/// SharedPtr<Sub> sub = super.cast<Sub>();
/// poco_assert (sub.get());
{
Other *pOther = dynamic_cast<Other *>(_ptr);
if (pOther)
return SharedPtr<Other, RC, RP>(_pCounter, pOther);
return SharedPtr<Other, RC, RP>();
}
template <class Other>
SharedPtr<Other, RC, RP> unsafeCast() const
/// Casts the SharedPtr via a static cast to the given type.
/// Example: (assume class Sub: public Super)
/// SharedPtr<Super> super(new Sub());
/// SharedPtr<Sub> sub = super.unsafeCast<Sub>();
/// poco_assert (sub.get());
{
Other *pOther = static_cast<Other *>(_ptr);
return SharedPtr<Other, RC, RP>(_pCounter, pOther);
}
C *operator->() { return deref(); }
const C *operator->() const { return deref(); }
C &operator*() { return *deref(); }
const C &operator*() const { return *deref(); }
C *get() { return _ptr; }
const C *get() const { return _ptr; }
operator C *() { return _ptr; }
operator const C *() const { return _ptr; }
bool operator!() const { return _ptr == 0; }
bool isNull() const { return _ptr == 0; }
bool operator==(const SharedPtr &ptr) const { return get() == ptr.get(); }
bool operator==(const C *ptr) const { return get() == ptr; }
bool operator==(C *ptr) const { return get() == ptr; }
bool operator!=(const SharedPtr &ptr) const { return get() != ptr.get(); }
bool operator!=(const C *ptr) const { return get() != ptr; }
bool operator!=(C *ptr) const { return get() != ptr; }
bool operator<(const SharedPtr &ptr) const { return get() < ptr.get(); }
bool operator<(const C *ptr) const { return get() < ptr; }
bool operator<(C *ptr) const { return get() < ptr; }
bool operator<=(const SharedPtr &ptr) const { return get() <= ptr.get(); }
bool operator<=(const C *ptr) const { return get() <= ptr; }
bool operator<=(C *ptr) const { return get() <= ptr; }
bool operator>(const SharedPtr &ptr) const { return get() > ptr.get(); }
bool operator>(const C *ptr) const { return get() > ptr; }
bool operator>(C *ptr) const { return get() > ptr; }
bool operator>=(const SharedPtr &ptr) const { return get() >= ptr.get(); }
bool operator>=(const C *ptr) const { return get() >= ptr; }
bool operator>=(C *ptr) const { return get() >= ptr; }
int referenceCount() const { return _pCounter->referenceCount(); }
protected:
C *deref() const {
if (!_ptr)
throw std::exception();
return _ptr;
}
void release() {
assert(_pCounter);
int i = _pCounter->release();
if (i == 0) {
RP::release(_ptr);
_ptr = 0;
delete _pCounter;
_pCounter = 0;
}
}
SharedPtr(RC *pCounter, C *ptr)
: _pCounter(pCounter), _ptr(ptr)
/// for cast operation
{
poco_assert_dbg(_pCounter);
_pCounter->duplicate();
}
protected:
RC *_pCounter;
C *_ptr;
template <class OtherC, class OtherRC, class OtherRP> friend class SharedPtr;
};
template <class C, class RC, class RP>
inline void swap(SharedPtr<C, RC, RP> &p1, SharedPtr<C, RC, RP> &p2) {
p1.swap(p2);
}
} // namespace Poco
#endif // Foundation_SharedPtr_INCLUDED
1 声望
0 粉丝
推荐阅读
滚蛋吧,正则表达式!
你是不是也有这样的操作,比如你需要使用「电子邮箱正则表达式」,首先想到的就是直接百度上搜索一个,然后采用 CV 大法神奇地接入到你的代码中?
良许赞 3阅读 1.6k
程序员适合创业吗?
大家好,我是良许。从去年 12 月开始,我已经在视频号、抖音等主流视频平台上连续更新视频到现在,并得到了不错的评价。每个视频都花了很多时间精力用心制作,欢迎大家关注哦~考虑到有些小伙伴没有看过我的视频,...
良许赞 3阅读 1.3k
记一次使用gdb诊断gc问题全过程
上次解决了GC长耗时问题后,系统果然平稳了许多,这是之前的文章《GC耗时高,原因竟是服务流量小?》 然而,过了一段时间,我检查GC日志时,又发现了一个GC问题,如下: 从这个图中可以发现,我们GC有一些尖峰,...
扣钉日记赞 2阅读 1.1k
使用kubeasz部署高可用kubernetes集群
本实验采用kubeasz作为kubernetes环境部署工具,它是一个基于二进制方式部署和利用ansible-playbook实现自动化来快速部署高可用kubernetes集群的工具,详细介绍请查看kubeasz官方。本实验用到的所有虚拟机默认软...
李朝阳赞 4阅读 789
Ubuntu20.04 从源代码编译安装 python3.10
Ubuntu 22.04 Release DateUbuntu 22.04 Jammy Jellyfish is scheduled for release on April 21, 2022If you’re ready to use Ubuntu 22.04 Jammy Jellyfish, you can either upgrade your current Ubuntu syste...
ponponon赞 1阅读 4.6k评论 1
麒麟操作系统 (kylinos) 从入门到精通 - 故障排查篇
OS平台:银河麒麟桌面操作系统(飞腾版)V10 SP1操作系统镜像:Kylin-Desktop-V10-SP1-General-Release-2203-ARM64
Oulaa赞 3阅读 1.6k
linux中用户登录加载配置文件的过程
shell的类型(站在用户登录登录的角度)登录式shell正常通过某终端登录su - USERNAMEsu -l USERNAME非登录式shellsu USERNAME图形终端下打开命令窗口自动执行的shell脚本用户登录时相关的bash配置文件全局配置文件/...
Dabric阅读 5.3k评论 3
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。