Application and traps of pre-declaration in C ++

Source: Internet
Author: User

The following is a detailed analysis of the application and trap of the pre-declaration in C ++. For more information, see

Use of pre-declaration
A friend with certain C ++ development experience may encounter such A scenario: Two Classes A and B are strongly coupled, and Class A must reference the objects of Class B, class B also references the object of Class. Well, it's not hard. My first instinct asked me to write this Code:

Copy codeThe Code is as follows:
// A. h
# Include "B. h"
Class
{

Public:
A (void );
Virtual ~ A (void );
};
// A. cpp
# Include "A. h"
A: A (void)
{
}
A ::~ A (void)
{
}
// B. h
# Include "A. h"
Class B
{
A;
Public:
B (void );
~ B (void );
};
// B. cpp
# Include "B. h"
B: B (void)
{
}
B ::~ B (void)
{
}


Well, complete. Compile A. cpp and fail. Compile B. cpp again, or fail. The compiler is dizzy. The Compiler compiles A. h and finds that it contains B. h. Compile B. h found that. h, but. h has already been compiled. (In fact, the compilation is not completed, and the compiler may have made A record.. h has been compiled to avoid endless loops. Compilation errors are always better than those in the dead loop), so the compilation will continue without re-compiling A. h. Later I found that the definition of A was used. Well, the definition of A was not compiled. Therefore, if the definition of A was not found, the compilation error occurred. The information is as follows:
1> d:/vs2010/test/a. h (5): error C2146: syntax error: missing '; 'before identifier' B'
1> d:/vs2010/test/a. h (5): error C4430: missing type specifier-int assumed. Note: C ++ does not support default-int
1> d:/vs2010/test/a. h (5): error C4430: missing type specifier-int assumed. Note: C ++ does not support default-int
What should we do?There is a solution. C ++ provides us with a pre-declaration. What is a pre-declaration? For example, I want to build a house (CHOuse). It's not enough to have a room. I still have to have a bed (CBed ). But the room hasn't been built yet. You can't buy a bed first. I have decided on the size of the bed and I will buy it another day. First, you have to build the house. When I build the house, I will leave a place for the bed. when the house is built, I will decide what kind of bed to buy. The pre-declaration means that when I declare a class (CHouse), I use another class definition (CBed), but the CBed has not yet been defined, in addition, I do not need the definition of CBed, as long as I know that CBed is a class. Well, I will first declare the class CBed and tell the compiler that CBed is a class (without the header file containing the CBed ):

Copy codeThe Code is as follows:
Class CBed;


Then CBed is used in CHouse, And the CBed pointer type is used (because the pointer type is fixed in size, but the CBed size can be determined only by knowing the CBed definition ). When CHouse definition is implemented, you must know the definition of CBed. That is to wrap the header file of CBed.

Pre-declaration is sometimes useful, for example, when two classes are mutually dependent. In addition, the pre-declaration can reduce the header file inclusion level and reduce the possibility of errors.The example above.

Copy codeThe Code is as follows:
// House. h
Class CBed; // when building a house: Do not buy it now. You must buy a bed.
Class CHouse
{
CBed * bed; // I will leave a location for the bed first.
Public:
CHouse (void );
Virtual ~ CHouse (void );
Void GoToBed ();
};
// House. cpp
# Include "Bed. h"
# Include "House. h" // wait for the House to be renovated. you have to buy a bed.
CHouse: CHouse (void)
{
Bed = new CBed (); // put the bed into the house
}
CHouse ::~ CHouse (void)
{
}
Void CHouse: GoToBed ()
{
Bed-> Sleep ();
}
// Bed. h
Class CBed
{
Public:
CBed (void );
~ CBed (void );
Void Sleep ();
};
// Bed. cpp
# Include "Bed. h"
CBed: CBed (void)
{
}
CBed ::~ CBed (void)
{
}
Void CBed: Sleep ()
{
}


Traps in pre-declaration
Note the following traps:
1. CBed * bed; pointer or reference is required
Reference version:

Copy codeThe Code is as follows:
// House. h
Class CBed; // when building a house: Do not buy it now. You must buy a bed.
Class CHouse
{
CBed & bed; // I will leave a location for the bed first.
// CBed bed; // compilation Error
Public:
CHouse (void );
CHouse (CBed & bedTmp );
Virtual ~ CHouse (void );
Void GoToBed ();
};
// House. cpp
# Include "Bed. h"
# Include "House. h" // wait for the House to be renovated. you have to buy a bed.
CHouse: CHouse (void)
: Bed (* new CBed ())
{
CBed * bedTmp = new CBed (); // put the bed into the house
Bed = * bedTmp;
}
CHouse: CHouse (CBed & bedTmp)
: Bed (bedTmp)
{
}
CHouse ::~ CHouse (void)
{
Delete & bed;
}
Void CHouse: GoToBed ()
{
Bed. Sleep ();
}


2. The CBed method cannot be used in the CHouse statement.
The undefined type CBed is used;
Bed-> the left side of Sleep must point to the class/structure/Union/generic type.

Copy codeThe Code is as follows:
Class CBed; // when building a house: Do not buy it now. You must buy a bed.
Class CHouse
{
CBed * bed; // I will leave a location for the bed first.
// CBed bed; // compilation Error
Public:
CHouse (void );
Virtual ~ CHouse (void );
Void GoToBed ()
{
Bed-> Sleep (); // An error occurred while compiling. I didn't buy any beds. How can I go to bed?
}
};


3. Call the CBed destructor before the CBed definition.

Copy codeThe Code is as follows:
// House. h
Class CBed; // when building a house: Do not buy it now. You must buy a bed.
Class CHouse
{
CBed * bed; // I will leave a location for the bed first.
// CBed bed; // compilation Error
Public:
CHouse (void );
Virtual ~ CHouse (void );
Void GoToBed ();
Void RemoveBed ()
{
Delete bed; // I don't need a bed. I want to remove it. How can I split it before I buy it?
}
};
// House. cpp
# Include "Bed. h"
# Include "House. h" // wait for the House to be renovated. you have to buy a bed.
CHouse: CHouse (void)
{
Bed = new CBed (); // put the bed into the house
}
CHouse ::~ CHouse (void)
{
Int I = 1;
}
Void CHouse: GoToBed ()
{
Bed-> Sleep ();
}
// Bed. h
Class CBed
{
Int * num;
Public:
CBed (void );
~ CBed (void );
Void Sleep ();
};
// Bed. cpp
# Include "Bed. h"
CBed: CBed (void)
{
Num = new int (1 );
}
CBed ::~ CBed (void)
{
Delete num; // call failed
}
Void CBed: Sleep ()
{
}
// Main. cpp
# Include "House. h"
Int main ()
{
CHouse house;
House. RemoveBed ();
}


The pre-declaration solves the mutual dependency between the two classes.
Next, give the answer to the first question:

Copy codeThe Code is as follows:
// A. h
Class B;
Class
{
B * B;
Public:
A (void );
Virtual ~ A (void );
};
// A. cpp
# Include "B. h"
# Include "A. h"
A: A (void)
{
B = new B;
}
A ::~ A (void)
{
}
// B. h
Class;
Class B
{
A;
Public:
B (void );
~ B (void );
};
// B. cpp
# Include "A. h"
# Include "B. h"
B: B (void)
{
A = New;
}
B ::~ B (void)
{
}


Application of pre-declaration in youyuan Method
C ++ Primer 4 Edition in the "youyuan" Chapter of the class, if you declare the member functions of another class B as the youyuan function F in the declaration of Class, class A must know the definition of Class B in advance; Class B's membership function F declares that if Class A is used as the form parameter, it must also know the definition of Class, then the two classes are mutually dependent. To solve this problem, you must use the pre-declaration of the class. For example:

Copy codeThe Code is as follows:


// House. h
# Include "Bed. h"
Class CHouse
{
Friend void CBed: Sleep (CHouse &);
Public:
CHouse (void );
Virtual ~ CHouse (void );
Void GoToBed ();
Void RemoveBed ()
{
}
};
// House. cpp
# Include "House. h"
CHouse: CHouse (void)
{
}
CHouse ::~ CHouse (void)
{
Int I = 1;
}
Void CHouse: GoToBed ()
{
}
// Bed. h
Class CHouse;
Class CBed
{
Int * num;
Public:
CBed (void );
~ CBed (void );
Void Sleep (CHouse &);
};
// Bed. cpp
# Include "House. h"
CBed: CBed (void)
{
Num = new int (1 );
}
CBed ::~ CBed (void)
{
Delete num;
}
Void CBed: Sleep (CHouse & h)
{
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.