代码之家  ›  专栏  ›  技术社区  ›  peterchen

c++:引用父级的成员

  •  2
  • peterchen  · 技术社区  · 15 年前

    我正在寻找一个好的模式来实现以下内容:

    class Outer;
    
    
    class Inner
    {
         Outer * m_outer;
    
       public:
         InitOuter(Outer * o) { m_outer = o; }
    }
    
    class Outer
    {
        Inner  m_inner;
    
      public:
        Outer()
        {
          m_inner.InitOuter(outer);
        }
    }
    
    • 创建内部时应始终引用外部
    • m\u outer永远不会为空
    • Inner

    不幸的是,据我所知, m_outer

    Inner::Inner(Outer & o) : m_outer(o) {}
    Outer::Outer() : m_inner(*this) {}
    

    因为在初始化 m_inner Outer 不是完全构造的因此 this 无效(在进一步初始化过程中也可能更改)。

    我找到的唯一选择就是 内部 非公开,以及 外部 他的朋友 内部 . 这样好一点,但是“朋友”关系似乎很强(因为通常内部类应该封装功能)。


    动机:在我对C++的理解中,“外”还没有完全构建,所以访问


    不,我不需要控制反转。真的,谢谢你,但是不行。

    2 回复  |  直到 15 年前
        1
  •  8
  •   Johannes Schaub - litb    15 年前
    Inner::Inner(Outer & o) : m_outer(o) {}
    Outer::Outer() : m_inner(*this) {}
    

    Inner 可以是一个嵌套类(对于迭代器之类的东西,这很有意义。

    你还没说你想做什么模特。需要注意的是,Outer还需要有自己的复制构造函数和复制赋值操作符,或者禁用它。否则,一份平装本将造成重大灾难。

        2
  •  3
  •   Matt Davis    15 年前

    this 初始化列表中的指针使用Visual Studio 2008生成编译器警告C4355。根据文档,不建议这样做,因为您正在将指向未构造对象的指针传递给另一个对象。如果另一个对象的构造函数访问未构造对象的任何成员或调用其方法,则结果是未定义的。

    但是,在您展示的有限场景中,您不会做任何会导致未定义行为的事情。你只是在设置 m_outer 变量以指向/引用未构造的对象。只要您将其限制在这个范围内,您就可以这样做,前提是编译器警告不是显示停止符(我们的项目有一个标准,所有编译器警告都将被删除)。

    如果这仍然困扰着你,你可以这样修改代码。

    class Outer; 
    
    class Inner 
    { 
         const Outer & m_outer; 
    
       public:
         Inner(const Outer & o) : m_outer(o)
         {
         }
    } 
    
    class Outer 
    { 
        Inner * m_inner; 
    
      public: 
        Outer() 
        { 
            m_inner = new Inner(*this);
        } 
    }