2017-11-10 22 views
1

私はワールドクラスとエンティティクラスを持っています。 ワールドクラスは新しいEntitiesを作成し、それに対するポインタを返します。 もしポインタが有効なEntityを指しているのかどうかわかりませんが、shared_ptrが解放されるまでEntityが削除されないのでshared_ptrを使いたくありません。だから私は、このポインタでcameupいくつかの時間後:C++誰でもこの種のポインタについて知っていますか?

#include <iostream> 
#include <unordered_map> 

template<class T> 
class Pointer 
{ 
public: 

    Pointer() :m_ptr(nullptr){} 
    Pointer(T*p) :m_ptr(p) { m_ptr->addPtr(this); } 

    ~Pointer() { if(valid()) m_ptr->removePtr(this); } 

    Pointer(const Pointer &other) :m_ptr(other.m_ptr) 
    { 
     if(valid()) 
      m_ptr->addPtr(this); 
    } 

    Pointer& operator=(const Pointer& other) 
    { 
     if (valid()) 
      m_ptr->removePtr(this); 

     m_ptr = other.m_pObj; 

     if (valid()) 
      m_ptr->addPtr(this); 

     return *this; 
    } 

    T* operator->() { return m_ptr; } 
    T* operator*() { return *m_ptr; } 

    T* get() { return m_ptr; } 
    bool valid() { return m_ptr != nullptr; } 

private: 

    template<typename T> 
    friend class PointerCollector; 

    T * m_ptr; 

}; 

template <class T> 
class PointerCollector 
{ 
public: 

    PointerCollector() = default; 
    virtual ~PointerCollector() 
    { 
     for (auto &x : m_ptrList) 
     { 
      (x.second)->m_ptr = nullptr; 
     } 
    } 

private: 

    void addPtr(Pointer<T> *ptr) 
    { 
     m_ptrList[ptr] = ptr; 
    } 
    void removePtr(Pointer<T> *ptr) 
    { 
     m_ptrList.erase(ptr); 
    } 

    template<typename T> 
    friend class Pointer; 

    std::unordered_map<Pointer<T>*, Pointer<T>*> m_ptrList; 
}; 


class Test : public PointerCollector<Test> 
{ 
public: 
    Test() {} 
    ~Test() = default; 

    int getVal() { return m_val; } 

private: 

    int m_val = 100; 
}; 



void func(Pointer<Test> ptr) 
{ 
    if (ptr.valid()) 
    { 
     std::cout << ptr->getVal(); 
    } 
    else 
    { 
     std::cout << "Invalid!\n"; 
    } 

} 

int main() 
{ 
    Test* myTest = new Test(); 

    Pointer<Test> myPtr(myTest); 
    Pointer<Test> myPtr2(myPtr); 

    delete myTest; 

    func(myPtr2); 


    getchar(); 
    return 0; 
} 

Testクラスは、それへのポインタを収集し、クラスが削除される場合は、それらを無効にします。

誰かがこの種のポインタに関するより良い実装やより多くの情報を知っているかどうかを尋ねたかったのです。

私がコンパイルされ、答えはイエス、このパターンは、多くの人々によって以前に使用されてきている2017

+4

あなたの最初の段落で説明したユースケースは、 'shared_ptr'を返すことで満たされます.Worldが' weak_ptr'を保持します –

+0

投稿したコードに 'World'と' Entity'はありますか? – Barmar

+1

投稿したコードはコンパイルされません。実際にコンパイルしてテストしたコードを投稿するのに役立ちます。コードが何をすべきかについての説明を提供する –

答えて

2

のVisual Studioで上記のコードをテストしました。あなたはちょうど貧乏人を作成しました(少なくとも1つの完全なバグと準最適ないくつかのものがあるので壊れました)、::std::weak_ptr<T>の再実装。代わりにそれを使用することを検討する必要があります。

関連する問題