gc_cleanupを継承するように書き換えることができればいいが、それも面倒な場合がある。
一度スマートポインタ的なものを試した。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef GC_PTR_HPP_ | |
#define GC_PTR_HPP_ | |
class gc_cleanup; | |
template <typename T> | |
class gc_ptr : public gc_cleanup | |
{ | |
T *ptr; | |
const P<T> &operator =(T *); | |
public: | |
P(T *t) : ptr(t) {} | |
operator T *() { return ptr; } | |
T *operator ->() { return ptr; } | |
~P() { delete ptr; } | |
}; | |
#endif |
逆に不便になった。(というか、スマートポインタを使いたくないからBoehm GCを使っている)
placement newというものを使うとコンストラクタのメモリ確保をフックできるようなので、それで試してみた。
たとえば new (gc_cleanup_alloc<std::vector<int > >()) std::vector<int>() のように使う。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef GC_CLEANUP_ALLOC_H_ | |
#define GC_CLEANUP_ALLOC_H_ | |
#ifdef __cplusplus | |
#include <new> | |
// C++用。allocで使う。 | |
template <typename T> | |
static void gc_cleanup_alloc_func(void *pself, void *) | |
{ | |
GC_REGISTER_FINALIZER_NO_ORDER(t, NULL, NULL, NULL, NULL); | |
static_cast<T *>(pself)->~T(); | |
} | |
template <typename T> | |
class GCCleanupAllocTag {}; | |
// usage: T *t = new (gc_cleanup_alloc<T>()) T(); | |
template <typename T> | |
inline AllocTag<T> gc_cleanup_alloc() | |
{ | |
return GCCleanupAllocTag<T>(); | |
} | |
// std::bad_allocを投げる。 | |
template <typename T> | |
inline void *operator new(std::size_t size, const AllocTag<T> &) | |
{ | |
void *t = GC_MALLOC(size); | |
if (t == NULL) { throw std::bad_alloc(); } | |
GC_REGISTER_FINALIZER_NO_ORDER(t, gc_cleanup_alloc_func<T>, NULL, NULL, NULL); | |
return t; | |
} | |
// see http://parashift.com/c++-faq-lite/dtors.html [11.14] | |
template <typename T> | |
inline void operator delete(void *t, const AllocTag<T> &) | |
{ | |
GC_REGISTER_FINALIZER_NO_ORDER(t, NULL, NULL, NULL, NULL); | |
GC_FREE(t); | |
} | |
#endif /* defined(__cplusplus) */ | |
#endif /* !defined(GC_CLEANUP_ALLOC_H_) */ |
0 件のコメント:
コメントを投稿