如何使用向前声明的类的成员函数

How can I use a member function of a forward declared class?

本文关键字:函数 成员 声明 何使用      更新时间:2023-10-16

我有2类A和B类,以下4个文件:

A.H

#ifndef A_H
#define A_H
#include "B.h"
class A {
public:
    A();
    int functionA();
    B objectB;
};
#endif //A_H

b.h

#ifndef B_H
#define B_H
class A;
class B {
public:
    B();
    int functionB();
    A * objectA;
};
#endif //B_H

A.CPP

#include "A.h"
A::A(){}
int A::functionA() {
    return 11;
}

b.cpp

#include "B.h"
B::B(){}
int B::functionB() {
    return objectA->functionA();
}

现在我使用该行进行编译:g++ A.cpp B.cpp -Wall -Wextra -O2 -march=native -std=gnu++1z

我得到此错误:

B.cpp: In member function 'int B::functionB()':
B.cpp:4:19: error: invalid use of incomplete type 'class A'
     return objectA->functionA();
                   ^
In file included from B.cpp:1:0:
B.h:1:7: note: forward declaration of 'class A'
 class A;
       ^

如何使用此处声明的函数的成员类?

查看编译B.cpp时所包含的内容,您有一个A类的正向声明,但不是真实的定义。因此,在第4行的B.cpp中,functionA是编译器未知的,因此您的类型不完整。

您应该在B.cpp中包括A.h

A.cpp中,包括A.h B.h
B.cpp中,包括B.h A.h

它的作用是因为:

  1. 我们没有循环包含(一个包含另一个标头文件的标题文件,其中包括原始文件)
  2. 每个类实现"看到"另一类的外观,但不是如何实现,我们不会破坏"与实现"规则的界面分离。在某些情况下,我们不这样做,但是在大多数情况下,它是有效的。

拇指规则(只有拇指规则!)是在使用该类的每个.cpp文件中包括类标头。因此,如果foo.cpp使用类bar,并且bar类接口在bar.h中,则foo.cpp应包括bar.h。我们没有遵循该规则的一些具体情况,但是在大多数情况下,它是有效的。

使用只有向前声明的类的成员是不可能的。

如果您的代码使用成员函数,则应完全声明该类,因为编译器需要检查具有此名称的成员函数是否实际上存在。