如何使用前向声明 class 的成员函数?
How can I use a member function of a forward declared class?
我有 2 个 classes 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;
^
如何使用此处声明的函数 forward 的成员 class?
在A.cpp
中,包括A.h
和B.h
在 B.cpp
中,包括 B.h
和 A.h
.
之所以有效,是因为:
- 我们没有循环包含(一个 header 文件包含另一个 header 文件,其中包含原始文件)
- 每个 class 实现 "sees" 另一个 class 看起来如何,但不是它是如何实现的,我们不会违反 "separation of interface from implementation" 规则。在某些情况下我们不这样做,但在大多数情况下,它是有效的。
经验法则(只是经验法则!)是在每个使用 class 的 .cpp
文件中包含 class header。所以如果 foo.cpp
使用 class bar
,并且 class bar
接口在 bar.h
中,那么 foo.cpp
应该包括 bar.h
。在某些特定情况下我们不遵循该规则,但在大多数情况下,它是有效的。
看看编译时包含了什么B.cpp
,你有classA
的前向声明,但不是真正的定义。所以在第 4 行的 B.cpp
中,编译器不知道 functionA
因此你的类型不完整。
您应该在 B.cpp
中包含 A.h
。
仅通过前向声明使用 class 的成员是不可能的。
如果您的代码使用成员函数,则 class 应该完整声明,因为编译器需要检查具有此名称的成员函数是否实际存在。
我有 2 个 classes 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;
^
如何使用此处声明的函数 forward 的成员 class?
在A.cpp
中,包括A.h
和B.h
在 B.cpp
中,包括 B.h
和 A.h
.
之所以有效,是因为:
- 我们没有循环包含(一个 header 文件包含另一个 header 文件,其中包含原始文件)
- 每个 class 实现 "sees" 另一个 class 看起来如何,但不是它是如何实现的,我们不会违反 "separation of interface from implementation" 规则。在某些情况下我们不这样做,但在大多数情况下,它是有效的。
经验法则(只是经验法则!)是在每个使用 class 的 .cpp
文件中包含 class header。所以如果 foo.cpp
使用 class bar
,并且 class bar
接口在 bar.h
中,那么 foo.cpp
应该包括 bar.h
。在某些特定情况下我们不遵循该规则,但在大多数情况下,它是有效的。
看看编译时包含了什么B.cpp
,你有classA
的前向声明,但不是真正的定义。所以在第 4 行的 B.cpp
中,编译器不知道 functionA
因此你的类型不完整。
您应该在 B.cpp
中包含 A.h
。
仅通过前向声明使用 class 的成员是不可能的。
如果您的代码使用成员函数,则 class 应该完整声明,因为编译器需要检查具有此名称的成员函数是否实际存在。