【问题标题】:Class reference to parent类对父级的引用
【发布时间】:2010-03-06 14:28:42
【问题描述】:

我在使用 C++ 方面还很陌生,实际上我遇到了一个问题。

我有一些 A、B、C 类定义如下(伪代码)

class A
{
...
    DoSomething(B par1);
    DoSomething(C par1);
...
}

class B
{
   A parent;
...
}

class C
{
   A parent;
...
}

问题是:

这个怎么做?如果我只是这样做(就像我一直在 c# 中所做的那样),它会给出错误。我非常了解这其中的原因。 (如果我将 B 和 C 的引用(包含)添加到它自己的标题中,则 A 尚未声明)

有什么办法可以解决这个问题? (恕我直言,使用 void* 指针不是方法)

【问题讨论】:

  • 你想让A成为B和C的父类吗?
  • 另一件事:你真的没有对 B 和 C 中的父级的 reference。如果你有:A a; B b(a); C c(a); 那么将有三个不相关的 A 实例,而不是一个实例有两个对象引用它。如果这是您想要的,请使用指向 A 成员的指针。

标签: c++ oop class parent-child


【解决方案1】:

Forward-declareBC。这样编译器就会在你到达 A 类的定义之前知道它们的存在。

class B;
class C;

// At this point, B and C are incomplete types:
// they exist, but their layout is not known.
// You can declare them as function parameters, return type
// and declare them as pointer and reference variables, but not normal variables.
class A
{
    ....
}

// Followed by the *definition* of B and C.

P。 S.

另外,还有一个与问题无关的提示(看看你是如何来自 C# 背景的):it's better to pass by const reference than by value:

class A
{
...
    void DoSomething(const B& par1);
    void DoSomething(const C& par1);
...
}

【讨论】:

    【解决方案2】:

    对于函数声明,如果函数未在此处定义,则允许参数类型不完整:

    class B;
    class C;
    
    class A
    {
    ...
        R DoSomething(B par1);
        R DoSomething(C par1);
    ...
    }
    
    class B
    {
       A parent;
    ...
    }
    
    class C
    {
       A parent;
    ...
    }
    
    inline R A::DoSomething(B par1) { ... }
    inline R A::DoSomething(C par1) { ... }
    

    所以你只需在 BC 完成后定义它们。但是由于它们是在类之外定义的,所以将它们设为inline,这样不同翻译单元中的多个定义就不会导致链接器错误。

    【讨论】:

    • 也只需确保您确实要复制参数。根据您的需要,也许通过引用传递它们,例如 DoSomething(B& par1) 会是最好的。
    【解决方案3】:

    您应该在 A 之前转发声明 B 和 C 类:

    class B;
    class C;
    
    class A {
        ...
    };
    

    在 A 中引用 B 和 C 时,编译器只需要知道这些是什么动物。使用前向声明,您可以满足编译器的要求。然后你就可以正确定义它们了。

    【讨论】:

      【解决方案4】:

      使用前向声明

      你可以定义A类;没有它的实现,在B和C之前,然后再定义它

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-04-09
        • 2013-08-04
        • 2018-09-25
        • 2013-03-29
        • 2012-12-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多