C++前置声明
【1】一般的前置函数声明
见过最多的前置函数声明,基本格式代码如下:
1 #include <iostream> 2 using namespace std; 3 4 void fun(char ch, int *pValue, double dValue); 5 6 void main() 7 { 8 int nValue = 100; 9 double dValue = 111.22; 10 fun('a', &nValue, dValue); 11 12 system("pause"); 13 } 14 15 void fun(char ch, int *pValue, double dValue) 16 { 17 return; 18 }
很好理解,不做赘述。
【2】自定义类型的前置声明
自定义类型的前置声明,由于编译器不知道类型的大小,所以不可以声明类型的对象。只可以利用类型声明指针和引用。
代码如下:
1 /* 2 * 自定义类型前置声明 3 */ 4 #include <iostream> 5 using namespace std; 6 7 class B; 8 9 class A 10 { 11 private: 12 // 内置类型 13 int m_nInt; 14 int& m_nRInt; 15 int* m_pInt; 16 17 // 自定义类型 18 // B b; // error! 19 B* m_pB; 20 B& m_b; 21 22 public: 23 A (B *pBPara = NULL) : m_nInt(100) 24 , m_nRInt(m_nInt) 25 , m_pInt(NULL) 26 , m_pB(NULL) 27 , m_b((NULL == pBPara) ? (*m_pB) : (*pBPara)) 28 { 29 cout << "A()" << endl; 30 } 31 ~A() 32 { 33 cout << "~A()" << endl; 34 } 35 36 void funA() 37 { 38 // m_pB->doAnything(); // build error C2027: use of undefined type 'B' 39 } 40 }; 41 42 class B 43 { 44 private: 45 int m_n; 46 47 public: 48 B (int n = 100) : m_n(n) 49 { 50 cout << "B()" << endl; 51 } 52 ~B() 53 { 54 cout << "~B()" << endl; 55 } 56 void doAnything() 57 { 58 cout << "B::anythig()" << endl; 59 } 60 }; 61 62 void main() 63 { 64 A objA; 65 system("pause"); 66 }
如上,利用前置类型的指针想调用其成员函数,会报编译错误!那么,肿么办?请看下文。
【3】声明和实现分离
代码如下,声明头文件:
1 /* 2 * TestForwardDeclar.h 3 */ 4 #ifndef D_TESTFORWARDDECLAR_H_ 5 #define D_TESTFORWARDDECLAR_H_ 6 7 #include <iostream> 8 9 class B; // 前置声明自定义类型 10 11 class A 12 { 13 private: 14 // 内置类型 15 int m_nInt; 16 int& m_nRInt; 17 int* m_pInt; 18 19 // 自定义类型 20 // B b; // error! 21 B* m_pB; 22 B& m_b; 23 24 public: 25 A (B *pBPara = NULL); 26 ~A (); 27 void funA(); 28 }; 29 30 class B 31 { 32 private: 33 int m_n; 34 35 public: 36 B (int n = 100); 37 ~B (); 38 void doAnything(); 39 }; 40 41 #endif
代码如下,定义文件:
1 /* 2 * TestForwardDeclar.cpp 3 */ 4 5 #include "TestForwardDeclar.h" 6 #include <iostream> 7 8 A::A (B *pBPara) 9 : m_nInt(100) 10 , m_nRInt(m_nInt) 11 , m_pInt(NULL) 12 , m_pB(NULL) 13 , m_b((NULL == pBPara) ? (*m_pB) : (*pBPara)) 14 { 15 std::cout << "A()" << std::endl; 16 } 17 18 A::~A() 19 { 20 std::cout << "~A()" << std::endl; 21 } 22 23 void A::funA() 24 { 25 m_pB->doAnything(); // 分开头文件和实现文件即可 26 } 27 28 29 B::B (int n) : m_n(n) 30 { 31 std::cout << "B()" << std::endl; 32 } 33 34 B::~B() 35 { 36 std::cout << "~B()" << std::endl; 37 } 38 39 void B::doAnything() 40 { 41 std::cout << "B::anythig()" << std::endl; 42 }
代码如下:测试文件:
1 #include "TestForwardDeclar.h" 2 3 void main() 4 { 5 A objA; 6 }
编译成功,运行结果是期望效果。
【4】总结
自定义类型前置声明时,只可以利用类型名声明指针和引用变量(谨记不可以声明对象或new 对象,均因为类型大小不确定,编译器无能为力)。
若需要利用指针或引用调用前置类型的接口,必须按照声明和实现分离的方式进行编码。
Good Good Study, Day Day Up.
顺序 选择 循环 总结