Today write C++primer 5th Chinese version of the No. 422 page of the program, there is "do not allow the use of incomplete type" error, the following I use Class A and Class B as a representative, reproduce the error, and propose a solution.
Class design with Problem A:
1, class A placed in the A.h and A.cpp
2, because B needs to access the private members of a, so declare B is its friend class
3, a in the need to use their own as a parameter to create a new class B instance.
The code is as follows: A.cpp is an empty destructor implementation ... No, I wrote the main implementation in the A.h.
1 #pragmaOnce2#include <iostream>3 4 classB//declare b so that it can be declared as a friend class below5 classA6 {7 Public:8FriendclassB//Declaration B is a friend class9Ainta):d ata (a) {}Ten OneB pirnt ()//print a line of text and invoke the constructor of B: B (a &a, int secparam = 5) To create an instance of B A { -Std::cout <<"hehe"<<Std::endl; - returnB (* This); the } -~A (); - Private: - intdata; +};
Second, the class design with the problem B
1, b accept a reference parameter, to achieve the purpose of constructing B
Similarly, B.cpp is also an empty constructor with an empty destructor, and the following shows the code in B.H:
1 #pragmaOnce2#include"A.h"3 classB4 {5 Public:6B (A &a,intSecparam =5):d ata (a.data) {}7 B ();8~B ();9 Ten Private: One intdata; A};
Third, the problem tip:
"B is not a complete data type" in A.h's 11th and 14 lines using B
Iv. Analysis
First, we need to declare B as a friend class in Class A, at which point Class B is not defined, so only class B is declared before Class A, and then code is written with B, but it is problematic:
This declaration is called a forward declaration, it is after the declaration, the time before the definition, it is incomplete, for the code in Class A, they do not know when B is defined, so the compiler directly think B is incomplete ...
If you include each other's header file separately in A.h and B.h, it also causes the loop to be included.
V. Solutions.
1. Write a B in a header file
2. Statement A, definition B
3. Define a
Code:
A.h
#pragmaOnce#include<iostream>classA//Statement aclassb{ Public: B (A&a,intSecparam =5);//can only be declared, cannot be defined here, specifically defined in B.cpp~B ();Private: intdata;};classa{ Public: FriendclassB//Declaration B is a friend classAinta):d ata (a) {} B pirnt ()//print a line of text and invoke the constructor of B: B (a &a, int secparam = 5) To create an instance of B{std::cout<<"hehe"<<Std::endl; returnB (* This); } ~A ();Private: intdata;};
B.cpp
" A.h " int secparam):d ata (a.data) {}b::~B () {}
For A.cpp, an empty constructor and destructor
Reason:
1. As mentioned above, it is incomplete and unusable within the time between the class declaration and the definition, but you can define pointers and references to this type, and you can declare (not define) a function that takes an incomplete type as a parameter or returns a type.
Therefore, you can first use the a& parameter in the constructor in B.
However, the implementation of the constructor that uses a& as a parameter (definition) needs to be written in CPP, so when it executes to CPP, A is already complete.
2. At the time of execution to a, the member declarations of B are complete.
An incomplete type of C + +