将引用从一个类保存到另一个类是否安全?

时间:2014-03-12 06:39:28

标签: c++

我有两个单身人士课程。

第一个是对第二个成员的引用。

#include <memory>

class B
{
    friend class A;
    public:
        static B& getInstance()
        {
            static B    instance;

            return instance;
        }
    private:
        B()
        : b(new int(5))
        , c(8)
        {};
        B(B const&);  
        void operator=(B const&);

        private:
            std::auto_ptr<int> b;
            int c;
};


class A
{
    public:
        static A& getInstance()
        {
            static A    instance;

            return instance;
        }
    private:
        A()
        : b(B::getInstance().b.get())
        , cRef(B::getInstance().c)
        {
        };
        A(A const&);  
        void operator=(A const&);
        private:
            int* b;
            int& cRef;
};

int main()
{
    return 0;
}

这段代码安全吗?

2 个答案:

答案 0 :(得分:2)

我想是的。这两个实例都是从程序生命周期的第一次访问开始。唯一可能变得棘手的是破坏:如果A的析构函数使用了B的引用/指针,但B已经被破坏了。幸运的是,3.6.3中的标准保证(引用2012年草案):

  

&#34;如果完成的构造函数或动态初始化   具有静态存储持续时间的对象在之前排序   另外,对第二个析构函数的完成进行了排序   在第一个析构函数启动之前。&#34;

(我强调。)换句话说,保证静态对象的逆向破坏顺序。由于您的施工顺序很好,破坏的顺序也是如此。 A的参考/指针B将在整个A实例销毁过程中有效。

答案 1 :(得分:0)

这里你对对象数据一无所知,所以这个代码在单线程环境中是正确的。在多线程中添加对getInstance()方法的锁定:

  static A& getInstance() {
       Lock lock;
       static A instance;
       return instance;
  }

但要注意B :: b存储为A中的指针。如果将来你能够改变B :: b,比如重置它,指针可能会变得不正确。

如果您的编译器在静态局部变量初始化部分支持C ++ 11标准(如@Mikhail注意到的那样),您可以避免这些锁定。

(顺便说一句:这些课程的目的是什么?没有公开的方法。)