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 粉丝
推荐阅读
关于 Ubuntu 20.04 LTS 的网络(dchp/dns/route/PPPoE)
前言旧时代网络管理软件 net-tools、NetworkManager新时代网络管理软件 iproute2、resolvectl新时代旧时代大致可按 2010 年划分检查网卡是否已插入网线直接查看文件 {代码...} ip addr 或 ip link 命令查看网卡状...
qbit赞 2阅读 14.9k
滚蛋吧,正则表达式!
你是不是也有这样的操作,比如你需要使用「电子邮箱正则表达式」,首先想到的就是直接百度上搜索一个,然后采用 CV 大法神奇地接入到你的代码中?
良许赞 4阅读 2.2k
又一款眼前一亮的Linux终端工具!
今天给大家介绍一款最近发现的功能十分强大,颜值非常高的一款终端工具。这个神器我是在其他公众号文章上看到的,但他们都没把它的强大之处介绍明白,所以我自己体验一波后,再向大家分享自己的体验。
良许赞 5阅读 1.7k
程序员适合创业吗?
大家好,我是良许。从去年 12 月开始,我已经在视频号、抖音等主流视频平台上连续更新视频到现在,并得到了不错的评价。每个视频都花了很多时间精力用心制作,欢迎大家关注哦~考虑到有些小伙伴没有看过我的视频,...
良许赞 3阅读 1.8k
Linux终端居然也可以做文件浏览器?
大家好,我是良许。在抖音上做直播已经整整 5 个月了,我很自豪我一路坚持到了现在【笑脸】最近我在做直播的时候,也开始学习鱼皮大佬,直播写代码。当然我不懂 Java 后端,因此就写写自己擅长的 Shell 脚本。但...
良许赞 1阅读 2.1k
Laravel入门及实践,快速上手ThinkSNS+二次开发
【摘要】自从ThinkSNS+不使用ThinkPHP框架而使用Laravel框架之后,很多人都说技术门槛抬高了,其实你与TS+的距离仅仅只是学习一个新框架而已,所以,我们今天来说说Laravel的入门。
ThinkSNS赞 1阅读 2.4k
confluence7.2.1的部署与迁移---呕心沥血版
Confluence是一个专业的企业知识管理与协同软件,也可以用于构建企业wiki。使用简单,但它强大的编辑和站点管理特征能够帮助团队成员之间共享信息、文档协作、集体讨论,信息推送。 到官网下载最新版本,截止目前...
暗涌阅读 7.8k
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。