参考博客:RAII 工厂
#include <bits/stdc++.h>
#define rep( i , j , n ) for ( int i = int(j) ; i < int(n) ; ++i )
#define dew( i , j , n ) for ( int i = int(n-1) ; i > int(j) ; --i )
#define _PATH __FILE__ , __LINE__
typedef std::pair < int , int > P ;
using std::cin ;
using std::cout ;
using std::endl ;
using std::string ;
namespace YHL {
// 作为管理资源的模板, 职责:1. 储存分配出去的指针 2. 释放指针资源
template< typename T >
class RAII_admin final {
private:
// 容器 litter 收集指针
std::deque<const void *> litter ;
RAII_admin(const RAII_admin&) = delete ;
RAII_admin& operator=(const RAII_admin&) = delete ;
public:
RAII_admin() { litter.clear() ; }
// RAII_admin 实例出了作用域会自动调用析构函数
~RAII_admin() {
cout << "有效生命期结束, 访问 RAII_admin 析构器\n" ;
while( !litter.empty() ) {
if ( const void *ptr = litter.back() ) {
litter.pop_back() ;
try {
cout << "ptr = " << ptr << endl ;
delete static_cast<const T*>(ptr) ;
ptr = nullptr ;
} catch (...) {
assert("Bad_RAII while delete") ;
}
}
}
}
// 储存(记录)分配出去的指针
T *emplace(T *ptr) {
assert(ptr) ;
litter.emplace_back(ptr) ;
return ptr ;
}
// 删除某个指针
bool erase(const T *ptr) {
assert(ptr) ;
for ( auto it = litter.begin() ; it != litter.end() ; ++it ) {
if ( ptr == *it ) {
it = litter.erase( it++ ) ; break ;
}
}
return true ;
}
int size() const { return litter.size() ; }
// 返回某个位置的指针
T* operator[](int pos) {
assert(pos < (int)litter.size()) ;
return const_cast<T*>(static_cast<const T*>(litter[pos]));
}
} ;
// 数据类型 T 的随意一个类
template< typename T >
class Entity {
public:
Entity(const T& _data) : data(_data) {}
virtual ~Entity() = default ;
T& get() { return data ; }
private:
T data ;
Entity() = delete ;
} ;
// 工厂类, 单一职能负责 create 制造; 其中 factory 管理好指针的资源
template<typename T>
class RAII_factory {
private:
RAII_admin< Entity<T> > factory ;
public:
Entity<T>* create(const T& data) {
return factory.emplace( new Entity<T>(data) ) ;
}
RAII_factory() = default ;
~RAII_factory() = default ;
RAII_admin< Entity<T> >& get() { return factory ; }
} ;
}
int main () {
using namespace YHL ;
RAII_factory<int> example ;
rep ( i , 0 , 10 )
cout << example.create(i + 1)->get() << endl ;
auto size = example.get().size() ;
rep ( i , 0 , size )
cout << example.get()[i]->get() << endl ;
Entity<int>* target[5] ;
rep ( i , 0 , 5 )
target[i] = example.get()[i] ;
rep ( i , 0 , 5 )
example.get().erase( target[i] ) ;
size = example.get().size() ;
rep ( i , 0 , size )
cout << example.get()[i]->get() << endl ;
return 0 ;
}