前向声明和#include类似,但是#include会增加编译时间,而且#include文件中可能有很多用不到的功能模块。
1、对于未定义的类,使用前要先前向声明。因为不知道类的具体细节,所以不能为类分配内存空间,但是指针和引用的内存空间是固定的,所以前向声明后只能使用对象指针以及对象引用,不能直接使用对象,更不能访问对象细节(java之所以可以循环引用就是使用了对象指针)
#include<stdio.h>
//class B;//注释掉前置声明会报错
class A{
public :
void func_A(B &b);
void printA(){
printf("printA\n");
}
private :
B b;
};
class B{
public:
void func_B(A a);
void printB(){
printf("printB\n");
}
};
int main(){
A a;
B b;
a.printA();
}
注释掉第2行的前置声明会编译报错如下
declaration.cpp:5:17: error: ‘B’ has not been declared
void func_A(B &b);
^
declaration.cpp:10:5: error: ‘B’ does not name a type
B *b;
去掉第2行注释编译还是报错:
declaration.cpp:10:7: error: field ‘b’ has incomplete type
B b;
将第10行的B b;改为B *b;就可以编译通过运行
printA
2、前向声明的类对象细节不可以在类内部成员函数使用,但是可以在适当位置类外部成员函数却可以
#include<stdio.h>
class B;
class A{
public :
void func_A(B &b){
b.printB();
}
void printA(){
printf("printA\n");
}
private :
B *b;
};
class B{
public:
void func_B(A a);
void printB(){
printf("printB\n");
}
};
int main(){
A a;
B b;
a.func_A(b);
}
编译报错
declaration.cpp: In member function ‘void A::func_A(B&)’:
declaration.cpp:6:10: error: invalid use of incomplete type ‘class B’
b.printB();
^
declaration.cpp:2:7: error: forward declaration of ‘class B’
class B;
将func_A的实现提到类外class B定义后的地方就可以访问B中的函数细节了
#include<stdio.h>
class B;
class A{
public :
void func_A(B* b);
void printA(){
printf("printA\n");
}
private :
B *b;
};
class B{
public:
void func_B(A a);
void printB(){
printf("printB\n");
}
};
void A::func_A(B* b){
b->printB();
}
int main(){
A a;
B b;
a.func_A(&b);
}
可以编译运行
printB