2013-03-18 46 views
1

比方說,我們有三個等級:A,B,C A和B都擁有一個指向C類應該不會發生那類A股同一指針兩個實例的對象C ,但是,在同一時間,對象C是自由地通過類B.唯一指針

的實例指出是否有實現該在C + +(11)的方法嗎?

======編輯======

好了,讓我們更詳細。當我創建對象C時,我將它們的指針添加到對象B中的容器中。對象A可能擁有或不具有指向C的指針。重要的是,不會有一個A指向可能由於用戶錯誤而實際發生的相同C。一旦A先驗地指向C,它應該始終指向C以表示它的一切。

我會去的唯一指針,但我需要他們的副本到B的容器!

+0

有很多不同的方式。指針是否改變?他們是否在施工中被分配?每創建一個'A'時創建一個'C'?當代碼嘗試將同一個指針分配給兩個'A'時會發生什麼? – 2013-03-18 15:16:38

+0

是的,但不是微不足道的。 – metal 2013-03-18 15:16:51

+0

'B'可以使用正常的指針。這種設計是可疑的,因爲它聽起來並不像獨特的所有權。 – Pubby 2013-03-18 15:18:16

回答

1

這聽起來像你想,如果相同的指針被分配到的A多個實例拋出異常。

該解決方案可以跟蹤使用的指針以防止重新分配。 它不是線程安全的 ...你將不得不修改這個來添加同步,如果你需要的話。

class A 
{ 
    // The pointers used by all instances of A 
    static std::set<C*> used_ptrs; 

    // The pointer used by this instance of A 
    C* the_c; 

    // Sets the pointer if it is valid 
    void set_c(C* c) 
    { 
    if (the_c) 
     throw std::runtime_error("C pointer is already set in this A"); 

    if (used_ptrs.count(c)) 
     throw std::runtime_error("C pointer is already set in another A"); 

    the_c = c; 
    used_ptrs.insert(c); 
    } 

    // The pointer is presumed to be unassigned at construction 
    A() : the_c(NULL) {} 

    // The pointer is removed from the set at destruction 
    ~A() 
    { 
    if(the_c); 
     used_ptrs.erase(the_c); 
    } 

    // Copying A is invalid by your description 
    A(const A&) = delete; 
    A& operator= (const A&) = delete; 
} 
+0

乾淨利落,恭喜! – DarioP 2013-03-19 13:34:40

0

我認爲你需要做一些記賬的內部在你的班上,也許使用靜態unordered_map成員。我已經測試了下面的代碼工作:

using namespace std; 

struct C; 

struct A 
{ 
    void SetPointerToC(C & aC) 
    { 
    if (mAllC.find(&aC) != mAllC.end()) 
     assert(false); // multiple instances of A should not point to the same C 

    mAllC[&aC] = this; 
    mC = &aC; 
    } 

    ~A() 
    { 
    mAllC.erase(mC); 
    } 

private: 

    // A is not copyable as to prevent multiple A instances having 
    // mC with the same value 
    A(const A &); 
    A & operator=(const A &); 

    static unordered_map<C*, A*> mAllC; 
    C * mC; 
}; 

unordered_map<C*, A*> A::mAllC; 

struct C 
{ 

}; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    A a;  
    A a2; 
    C c; 
    a.SetPointerToC(c); // works 
    a2.SetPointerToC(c); // assert! 

    return 0; 
}