【问题标题】:C++: parent pointer to class that includes the childC ++:指向包含子类的类的父指针
【发布时间】:2011-11-16 21:18:12
【问题描述】:

我有一个类设计问题可以用这个例子来简化:

// foo.h
#include "foo2.h" 
class foo
{
public:
    foo2 *child;
// foo2 needs to be able to access the instance
// of foo it belongs to from anywhere inside the class
// possibly through a pointer
};

// foo2.h
// cannot include foo.h, that would cause an include loop

class foo2
{
public:
    foo *parent;
// How can I have a foo pointer if foo hasn't been pre-processed yet?
// I know I could use a generic LPVOID pointer and typecast later
// but isn't there a better way?
};

除了使用泛型指针或将父指针传递给 foo2 成员的每个调用之外,还有其他方法吗?

【问题讨论】:

  • 我已经有一段时间没有做 C++ 了。但似乎你必须将父指针传递给你的类。您总是可以创建一个名为 parent 的属性并将其分配给父指针。
  • @Frank:问题在于编译器中的循环依赖。传递父指针并不是这里的棘手部分。

标签: c++ class pointers parent


【解决方案1】:

如果只使用指针,则不需要包含文件,如果将它们包含在 .cpp 文件中,则不会出现循环问题:

// foo.h
class foo2; // forward declaration
class foo
{
public:
    foo2 *child;
};

// foo2.h
class foo;
class foo2
{
public:
    foo *parent;
};

//foo.cpp
#include "foo.h"
#include "foo2.h"

//foo2.cpp
#include "foo2.h"
#include "foo.h"

尽管重新思考你的设计可能会让你变得更好。

【讨论】:

  • 非常感谢!多年来我一直在努力解决这个问题!
【解决方案2】:

转发声明是朋友:

// foo.h
class foo2;

class foo
{
  foo2 *pFoo2;
};

// foo2.h
#include "foo.h"
class foo2
{
  foo *pFoo;
};

不过,正如 Pubby 所说,需要相互了解的类可能应该只是一个类,或者可能是一个具有两个成员的类,这两个成员都知道父类,但不是双向关系.

就父母身份和通用性而言:

template  <class Parent>
class  ChildOf
{
public:
  // types
  typedef Parent  ParentType;

  // structors
  explicit ChildOf(Parent& p);
  ~ChildOf();

  // general use
  Parent&  GetParent();
  const Parent&  GetParent() const;

  void  SetParent(Parent& p);

private:
  // data
  Parent  *m_pParent;
};

/*
  implementation
*/
template  <class ParentType>
ChildOf<ParentType>::ChildOf(ParentType& p)
: m_pParent(&p)
{}

template  <class Parent>
ChildOf<Parent>::~ChildOf()
{}

template  <class ParentType>
inline
ParentType&  ChildOf<ParentType>::GetParent()
{
  return *m_pParent;
}

template  <class ParentType>
inline
const ParentType&  ChildOf<ParentType>::GetParent() const
{
  return *m_pParent;
}

template  <class ParentType>
void  ChildOf<ParentType>::SetParent(ParentType& p)
{
  m_pParent = &p;
}

【讨论】:

    【解决方案3】:

    您应该使用前向声明并在您的 cpp 中包含头文件

    // foo.h
    #ifndef FOO_H_
    #define FOO_H_
    class foo2;
    
    class foo
    {
    public:
        foo2 *child;
    };
    #endif
    
    // foo2.h
    #ifndef FOO_2_H_
    #define FOO_2_H_
    class foo;
    
    class foo2
    {
    public:
        foo *parent;
    };
    #endif
    

    【讨论】:

      【解决方案4】:

      使用forward declaration 告诉编译器foo2 是一个随后将被定义的类。

      class foo2;
      
      class foo {
          foo2 *child;
      };
      
      class foo2 {
          foo *parent;
      };
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-05-03
        • 2015-08-12
        • 2015-04-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多