4

C++ 要求在使用之前定义所有类型,这使得以正确的顺序包含头文件非常重要。美好的。但是我的情况呢:

Bunny.h

   班兔
   {
       ...
   私人的:
       参考<Bunny> 父级;
   }

编译器抱怨,因为在我在自己的类定义中使用它的时候,技术上还没有完全定义。Bunny因为我做了一些愚蠢的事情(无关)。

除了重写我的模板类Reference以使其采用指针类型(在这种情况下我可以使用 的前向声明Bunny)之外,我不知道如何解决这个问题。

有什么建议么?

编辑:我的Reference类(XObject是数据模式对象的基类):

模板 <class T = XObject> 类参考
{
上市:
    参考():m_ptr(NULL){}
    参考(T* p)
    {
        m_ptr = p;
        if (p != NULL) ((XObject*)p)->ref();
    }
    〜参考()
    {
        如果(m_ptr)
        {
            ((XObject*)m_ptr)->deref();
        }
    }

    // ... 赋值、比较等

私人的:
    T* m_ptr;
};

编辑:这工作正常,问题是别的。非常感谢你的帮助!

4

3 回答 3

3

您的问题的答案取决于 Reference<> 的样子。如果它有一个 Bunny 类型的实例变量,那么它当然不会工作(怎么会,你有一个永远不会结束的递归定义)。如果它只有引用和指针,那么它应该可以正常工作。模板实例化中的 Bunny 类型不会干扰这一点。

编辑(发布参考<>代码编辑):

我似乎无法重现您的问题。我已经重新实现了你正在做的代码,但它对我来说编译得很好:

struct base {
  void fun() {}
};
template < typename T >
struct temp
{
  T * t;

  void f() { ((base*)t)->fun(); }
};

struct test
{
  temp<test> t;

};

int main()
{
  test t;
  t.t.f();
}

这显然是无效代码,因为您将获得未定义的结果,但它确实可以编译。这里的主要问题是从 type test* 到 type base* 的重新解释。如果 test 确实确实从 base 继承,那么演员甚至都没有必要。像这样的代码不会按预期运行,但它应该编译得很好。我的一个建议是失去所有 c 风格的演员表。这不会解决你遇到的问题,不管它是什么......它必须在你没有粘贴的代码中的某个地方。

于 2010-06-03T19:06:59.747 回答
1

如果Reference<T>有一个类型的变量T,那么T就不能有一个类型的变量Reference<T>。您的替代方案是重写Reference<T>,或重写Bunny以使用指向Reference<T>

template<class> class Reference;

class Bunny
{
    ...
private:
    Reference<Bunny>* parent;
}
于 2010-06-03T19:05:13.177 回答
0

这不只是抽象的问题,抽象成为问题的解决方案吗?我会考虑创建一个接口,IBunny然后Reference<IBunny>在任何实现的定义中使用IBunny

这是发明接口的用例之一(在典型的 GoF 创建模式中派上用场)。

于 2010-06-03T19:17:43.727 回答