C++ 类中的唯一指针

C++ 类中的唯一指针,c++,class,c++11,smart-pointers,C++,Class,C++11,Smart Pointers,假设我们有三个类:A、B、C。A和B都有一个指向C类的指针。A类的两个实例不应该共享指向C对象的同一个指针,但同时,B类的实例可以自由指向C对象 有没有办法在c++(11)中实现这一点 =======编辑====== 好的,让我们来了解更多细节。当我创建对象C时,我将它们的指针添加到对象B中的容器中。对象a可能拥有或没有指向C的指针。重要的是,不会有多个a指向同一个C,这实际上可能是由于用户的错误造成的。一旦A先验地指向C,它就应该终生都指向C 我会去寻找唯一的指针,但我需要它们的副本到B的容器

假设我们有三个类:A、B、C。A和B都有一个指向C类的指针。A类的两个实例不应该共享指向C对象的同一个指针,但同时,B类的实例可以自由指向C对象

有没有办法在c++(11)中实现这一点

=======编辑======

好的,让我们来了解更多细节。当我创建对象C时,我将它们的指针添加到对象B中的容器中。对象a可能拥有或没有指向C的指针。重要的是,不会有多个a指向同一个C,这实际上可能是由于用户的错误造成的。一旦A先验地指向C,它就应该终生都指向C


我会去寻找唯一的指针,但我需要它们的副本到B的容器中

我认为您需要在类内部做一些簿记,也许可以使用静态
无序映射
成员。我已经测试了以下代码是否正常工作:

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;
}
使用名称空间std;
结构C;
结构A
{
无效设定值TOC(C&aC)
{
if(mAllC.find(&aC)!=mAllC.end()
assert(false);//的多个实例不应指向同一个C
mAllC[&aC]=这个;
mC=&aC;
}
~A()
{
mAllC.擦除(mC);
}
私人:
//A不可复制,以防止多个A实例具有
//具有相同值的mC
A(常数A&);
A&运算符=(常数A&);
静态无序映射mAllC;
C*mC;
};
无序地图A::mAllC;
结构C
{
};
int _tmain(int argc,_TCHAR*argv[]
{
A A;
A a2;
C C;
a、 SetPointerToC(c);//有效
a2.SetPointerToC(c);//断言!
返回0;
}

我认为你需要在课堂内部做一些簿记工作,也许可以使用一个静态的
无序映射
成员。我已经测试了以下代码是否正常工作:

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;
}
使用名称空间std;
结构C;
结构A
{
无效设定值TOC(C&aC)
{
if(mAllC.find(&aC)!=mAllC.end()
assert(false);//的多个实例不应指向同一个C
mAllC[&aC]=这个;
mC=&aC;
}
~A()
{
mAllC.擦除(mC);
}
私人:
//A不可复制,以防止多个A实例具有
//具有相同值的mC
A(常数A&);
A&运算符=(常数A&);
静态无序映射mAllC;
C*mC;
};
无序地图A::mAllC;
结构C
{
};
int _tmain(int argc,_TCHAR*argv[]
{
A A;
A a2;
C C;
a、 SetPointerToC(c);//有效
a2.SetPointerToC(c);//断言!
返回0;
}

如果将同一指针分配给
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;
}
A类
{
//对象的所有实例使用的指针
静态标准::设置使用的PTR;
//此实例使用的指针
C*联合会;
//设置指针是否有效
无效集_c(c*c)
{
如果(联合会)
throw std::runtime_error(“此A中已设置了C指针”);
如果(使用计数(c))
抛出std::runtime_错误(“C指针已在另一个A中设置”);
_c=c;
用过的插入物(c);
}
//假定指针在构造时未分配
A():_c(NULL){}
//指针在销毁时从集合中删除
~A()
{
若(教统会),;
已使用的清除(c);
}
//根据您的描述,复制文件无效
A(常数A&)=删除;
A&运算符=(常量A&)=删除;
}

如果将同一指针分配给
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;
}
A类
{
//对象的所有实例使用的指针
静态标准::设置使用的PTR;
//此实例使用的指针
C*联合会;
//设置指针是否有效
无效集_c(c*c)
{
如果(联合会)
throw std::runtime_error(“此A中已设置了C指针”);
如果(使用计数(c))
抛出std::runtime_错误(“C指针已在另一个A中设置”);
_c=c;
用过的插入物(c);
}
//假定指针在构造时未分配
A():_c(NULL){}
//指针在销毁时从集合中删除
~A()
{
若(教统会),;
已使用的清除(c);
}
//根据您的描述,复制文件无效
A(常数A&)=删除;
A&运算符=(常量A&)=删除;
}

有很多不同的方法。指针会改变吗?他们被分配到施工现场吗?是否每次创建
a
时都会创建
C
?当代码尝试将同一指针分配给两个
A
s时,会发生什么情况?是的,但这不是小事。
B
可以使用普通指针。这个设计很可疑,因为它听起来不像是唯一的所有权。A只是拥有一个指向C的指针,还是A是C的所有者,B只是引用它?也就是说,C的生存期是否与a的生存期绑定?顺便说一句,这听起来不像是C++11智能指针应该解决的问题。我认为最好的解决方案是A持有一个指向C的唯一指针,B存储一个指向C的原始指针。但是,B类型的对象并不“拥有”C,所以这可能是不可接受的。有很多不同的方法。指针会改变吗?他们被分配到施工现场吗?是否每次创建
a
时都会创建
C
?当代码尝试将同一指针分配给两个
A
s时,会发生什么情况?是的,但这不是小事。
B
可以使用普通指针。这个设计很可疑,因为它听起来不像是唯一的所有权。A只是拥有一个指向C的指针,还是A是C的所有者,B只是引用它?也就是说,C的生存期是否与t绑定