我正在为程序构建一个加载项。我的加载项操作宿主应用程序传递给我的Ptr对象。我想创建一个由主机创建的外部创建和管理对象的向量。不幸的是,文档没有任何明确的示例如何执行此操作。
class Players {
vector<Ptr<Player>> vectorOfGamers; // who deletes and when this?
public void CreatePlayers () {
// call static application to create three players
for ( int i = 0; i < 3; i++ )
vectorOfGamers.push_back(Application.GetNextPlayer());
}
}
如果构建此类并防止内存泄漏并在项目过早删除时导致空异常,则会感到困惑。另外,我如何使用现代C ++工具来实现这一目标,同时获得新内存管理的好处,如make_shared,make_unique,nullptr等?
为了您的信息,下面是Ptr的快照。我对Ptr感到困惑,因为它看起来多余,因为现代C ++的新内存管理设施。
class IncompleteType
{
public:
template<typename T> static void addref(void* ptr) { reinterpret_cast<adsk::core::ReferenceCounted*>(ptr)->addref(); }
template<typename T> static void release(void* ptr) { reinterpret_cast<adsk::core::ReferenceCounted*>(ptr)->release(); }
};
class CompleteType
{
public:
template<typename T> static void addref(T* ptr) { ptr->addref(); }
template<typename T> static void release(T* ptr) { ptr->release(); }
};
template<class T, class PT = IncompleteType>
class Ptr
{
public:
typedef T element_type;
Ptr() : ptr_(nullptr) {}
Ptr(const Ptr& rhs) : ptr_(nullptr) { reset(rhs.ptr_); }
Ptr(const T* ptr, bool attach = true) : ptr_(nullptr) { reset(ptr, attach); }
// casting constructor. call operator bool to verify if cast was successful
template<class V, class VPT>
Ptr(const Ptr<V, VPT>& rhs) : ptr_(nullptr) {
if (rhs)
reset(rhs->template query<T>(), false);
}
~Ptr() { reset(nullptr); }
void operator=(const Ptr<T, PT>& rhs) { if (&rhs != this) reset(rhs.ptr_); }
void operator=(const T* ptr) { reset(ptr, true); }
// casting assignment operator. call operator bool to verify if cast was successful
template<class V, class VPT>
void operator=(const Ptr<V, VPT>& rhs) {
if (rhs)
reset(rhs->template query<T>(), false);
else
reset(nullptr);
}
void reset(const T* ptr, bool attach = false) {
if (ptr_ != ptr)
{
if (ptr_)
PT::template release<T>(ptr_);
ptr_ = const_cast<T*>(ptr);
if (!attach && ptr_)
PT::template addref<T>(ptr_);
}
}
T* operator->() const { assert(ptr_ != nullptr); if (ptr_ == nullptr) throw std::exception(); return ptr_; }
// Test if this pointer is empty (if operator-> will throw)
/*explicit*/ operator bool() const { return ptr_ != nullptr; }
bool operator==(const Ptr& rhs) const { return ptr_ == rhs.ptr_; }
bool operator!=(const Ptr& rhs) const { return ptr_ != rhs.ptr_; }
bool operator<(const Ptr& rhs) const { return ptr_ < rhs.ptr_; }
// Iteration support. Only usable if T has count and item members and an iterable_type
typedef Iterator<T, PT> iterator;
iterator begin() const { return Iterator<T, PT>(*this); }
iterator end() const { return Iterator<T, PT>(*this, true); }
// Caution the following functions if used incorrectly can cause a reference count leak
T* get() const { return ptr_; }
T* detach() { T* t = ptr_; ptr_ = nullptr; return t; }
private:
T* ptr_;
};
答案 0 :(得分:1)
你可能是正确的,在后C ++ 03环境中不需要Ptr
。可能你的插件API已经足够老了,C ++ 11就不存在了。从您发布的代码中我最好的猜测是Ptr
应该是一个引用计数的智能指针,它管理像std::shared_ptr
这样的共享所有权。
您应该从plguin API文档以及主机程序的源代码中清楚地了解到这一点。只是从你发布的片段中,甚至没有提到程序的名称,就不可能说清楚了。