【问题标题】:error: member access into incomplete type : forward declaration of错误:成员访问不完整类型:前向声明
【发布时间】:2023-10-25 18:12:01
【问题描述】:

我在同一个 .cpp 文件中有两个类:

// forward
class B;

class A {       
   void doSomething(B * b) {
      b->add();
   }
};

class B {
   void add() {
      ...
   }
};

转发不起作用,我无法编译。

我得到这个错误:

error: member access into incomplete type 'B'
note: forward declaration of 'B'

我正在使用 clang 编译器 (clang-500.2.79)。

我不想使用多个文件(.cpp 和 .hh),我想只在一个 .cpp 上编写代码。

我不能在A类之前写B类。

您知道如何解决我的问题吗?

【问题讨论】:

  • A::doSomething的函数体移到class B的定义之后。
  • 我在线程中谈到了这一点:“我不能在 A 类之前写 B 类。”。我使用示例代码来解释我的问题。在我的真实代码中,我的 A 类中有一个指向我的 B 类的指针。所以,如果我在 A 类之前写 B 类,问题将是一样的!
  • 应避免使用以下划线开头的名称,例如_b。它们可以被全局命名空间中的编译器/标准库使用;此外,您应该切勿使用以下划线开头后跟大写字母的标识符,例如_B(也保留)。

标签: c++ forward-declaration


【解决方案1】:

doSomething 定义移到其类声明之外和B 之后,并通过public-ing 或friend-ing 使A 可以访问add

class B;

class A
{
    void doSomething(B * b);
};

class B
{
public:
    void add() {}
};

void A::doSomething(B * b)
{
    b->add();
}

【讨论】:

  • 遇到了类似的问题。我忘记在 .cpp 中包含标题(来自另一个类)
  • 如果 A 是一个模板类怎么办?那么你真的不能把它移到类声明之外......
【解决方案2】:

在使用该类之前,您必须具有类B定义。否则编译器怎么会知道存在B::add这样的函数?

要么在类A之前定义类B,要么将A::doSomething的主体移动到类B已经定义之后,比如

class B;

class A
{
    B* b;

    void doSomething();
};

class B
{
    A* a;

    void add() {}
};

void A::doSomething()
{
    b->add();
}

【讨论】: