2013-03-18 117 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; 
}