C ++: compilation unit, declaration and definition, header file function, prevent repeated reference of header files in the same compilation unit, static and anonymous Space

Source: Internet
Author: User

Transferred from: http://www.cnblogs.com/rocketfan/archive/2009/10/02/1577361.html

 

1. compilation unit: A. cc or. cpp file is used as a compilation unit to generate. O.

2. Definition and declaration of common data types, Function Definition and Declaration (class functions are the same ).

Extern int X; // The variable is declared and no actual address is allocated. No actual target code is generated.
Void print (); // function declaration, no actual target code is generated

For example, int X; int x = 3; void print () {}; // All are defined to generate the actual target code

The Declaration does not generate the actual target code. Its function is to tell the compiler, OK. After this compilation unit, or other compilation units will have this X variable and print letter.

Number. Otherwise, if the compiler finds that the program uses X, print (), and there is no declaration before, an error will be reported. If a declaration is not defined

An error is returned. (Note the period corresponding to the declaration and definition)

It is common to call print () in source. CC, while declare print () in head. H, and include head. h In source. CC, so there is a print sound.

It can be compiled, but if no print function is defined in all the compilation units (any. cpp file), the source. O unit is

An error occurs because it tries to use the print function but cannot find the print definition.

// Head. h

Void pirnt ();

// Source. CC

Void Foo (){

Print ();

}

Since the Declaration does not generate actual code, there can be multiple repeated declarations:
// Source1.cc
Extern int X;

// Source2.cc
Extern int X;

Even the same compilation unit can have multiple repeated declarations:

// Source1.cc
Extern int X;
Extern int X;

The definitions of common variables and functions cannot be repeated.

3. Duplicate symbols within the same compilation unit are blocked during the compilation period, and the cognominal symbols between different compilation units must be found in the linker.

If you are in a source1.cc
// Source1.cc
Int X;
Int X;

If int X; is specified twice, an error is reported during compilation. If:
// Source1.cc

Int X;

// Source2.cc
Int X;

There will be no errors in the compilation process, but in the Link process, because the target code contains two fully-local X, there will be a link error: X redefinition.

Different programmers may write different modules. How can they avoid this situation?Avoid duplicate namespace names.

The Google programming specification encourages the use of an anonymous space:

// Source1.cc
Namespace {
Int X;

}

// Source2.cc

Namespace {

Int X;

}

Okay, now there is no link error because two X names are not duplicated. Of course, for this simple example, you can use an unnamed namespace in source1.cc to avoid link

Wrong.

// Source1.cc

Namespace {

Int X;

}

// Source1.cc

Static int X;

What is the difference? It seems that the effect is the same. The difference is that X of the namespace still has external links, but because it is not named, other units cannot be linked.

To, if

Namespace Haha {

Int X;

}

In other units, haha: X can be used to access it. Static cannot be linked because it is an internal link feature.

4. header files.

// Head. h

Int X;

// Source1.cc

# Include "head. h"

// Source2.cc

# Include "head. h"

The header file is not compiled. The reference include "head. H" in. CC is to insert the content in head. H into. CC during pre-compilation.

In the above example, there is no problem during compilation, but an error occurs during the link because of the repeated global variable X.

Therefore, the variable definition, including the function definition, should not be written to the header file, because the header file may be referenced by multiple. CC files.

If head. H is written as follows, does it prevent redefinition errors during link X? (Note: It should be noted that many people do not know the white-headed files.

# Ifndef... # define... # endif scope and time)

// Head. h

# Ifndef _ head_h _

# DEFINE _ head_h _

Int X;

# Endif

// Source1.cc

# Include "head. h"

// Source2.cc

# Include "head. h"

Now, is there no problem with G ++-O test source1.cc source2.cc? The answer is no.

All header files should be added as above # ifndef # endif, but its function is to prevent the header files from being repeatedly referenced in the same compilation unit (# Ifndef # endif

The usage scope is: reference the compilation unit of this header file; the function time is: compilation period).

That is to say, it is possible to prevent:

// Source1.cc

# Include "head. h"

# Include "head. h"

In this case, of course we will not take the initiative to write the above form, but the following situation is likely to happen (nested inclusion ):

// Source1.cc

# Include "head. h"

# Inlcude "A. H"

// A. h

# Include "head. h"

In this way, the header file of the same compilation unit is repeatedly referenced, so soruc1.cc has two int X; definitions.

However, for different compilation units source1.cc, source2.cc will still reference head. H, even if # ifndef... # Endif still triggers a chain

An error occurred while redefinition.

5. Class declaration and definition.

Class A; // class declaration

The class declaration is the same as that of a common variable declaration. The object code is not generated and can be repeated in the same or multiple compilation units.

Class {

}; // Class definition

The definition of the class is a little special. You may wonder why int x cannot be put into. H (see figure 4), but you can put the definition of the class in the header.

What about repeated references in the file? At the same time, functions of the class are not defined in the inline (except for those written in the class definition) and cannot be written in the header file?

This is because the class definition only tells the compiler how the data format of the class is. After instantiation, the object occupies a large space, and the class definition does not generate the target code. Because

The only difference between the class definition and the declaration of common variables is that the class definition cannot appear multiple times in the same compilation unit.

// Source1.cc

Class;

Class A; // repeated class declaration, OK

Class {

};

Class {

};

Class {

Int X;

}; // If the class is repeatedly defined within the same compilation unit, an error will be reported during compilation because the compiler does not know what a is to be produced in the compilation unit.

If Class A {}; is defined in head. h, while head. h does not # ifndef... # Endif

Status.

However, in different compilation units, classes can be defined repeatedly because class definitions do not generate actual code.

// Source1.cc

Class {

}

// Source2.cc

Class {

} // Different compilation units, repeated class definition, OK! So the class definition can be written in the header file!

Differences between static and anonymouse namespace in C ++
I remember a colleague who asked me why I used anonymouse namespace in the program. When I thought about it, I replied that it was actually preserving locality (this is also my

Then someone said why not use static. Well, it seems that there is no difference between the two things at first glance, so I Googled myself and found a reason.

YesMember in anonymouse namespace (unknown space) has external links, but it cannot be accessed by external links! While static

The RootNo external links! In this case, a problem occurs. In the template, parameters of no type must have external links. Otherwise, compilation fails.

For example:

Template <void FN ()>
Class foobar
{};

Namespace
{
Void ABC ()
{
Wcout <_ T ("ABC") <Endl;
};
}
Static void EFG ()
{
Wcout <_ T ("EFG") <Endl;
};
Int _ tmain (INT argc, _ tchar * argv [])
{
Foobar <ABC> XYZ //! ; This line can be passed through
Foobar <EFG> RST ;//! Note that this line cannot be compiled.
Return 0;
}

Some people think that it is better to use anonymouse namespace because the static method is criticized by the C ++ 98 standard.

You can use anonymouse namespace instead of static.

// Source1.cc

Class {

}

// Source2.cc

Class {

Int X;

} // Different compilation units, OK

6. Summary

1. Write the declaration, function declaration, class definition, and inline function of variables in the header file. do not include variable definition, class function non-inline definition, and function definition. That is

The header file should not contain anything that may generate the target code.

2.Prevents repeated references to header files in a compilation unit# Ifndef… must be added to all header files... # Endif.

3. We recommend that you use an unnamed namespace in. CC to effectively prevent name conflicts between different compilation units.

4. For more professional information, see<Large-scale C ++ Program Design>The first chapter will provide an extremely complete introduction.

It is mentioned thatClass DefinitionIt has the internal link feature, that is, it is not a declaration and cannot be repeated in the same compilation unit, but it has an internal link (the so-called internal link

This indicates that the name is partial for the compilation unit and does not conflict with the same name in other compilation units during the link .)

It must be defined in a header file..

For the Declaration and definition, the definition in the book is:
A declaration introduces a name (Symbol) into a program, and a definition provides a unique description of an object (such as a type, instance, or function) in a program..

5. The first article is not very accurate.<Large-scale C ++ Program Design>Theoretically, the header file contains all the items with internal links,

Includes definitions with internal links. For example

Static int X;

Static void print (){};

But we do not advocate this because every. CC that contains this header file needs to open up a space to store this X,That is to say, different compilation unitsAll introduce static

Int xBecause they are internal links, they do not affect each other.

Even if you use namespace, as shown in. H

Namespace MySpace {

Static int X;

}

This header file is introduced in different. CC files, and the MySpace: X called in their respective compilation units is also different and does not affect each other!

The book mentions:

Const int width = 3; // see page 23 of the book.

This const variable should also be avoided in the header file.

However, similar to the previous C language, # define width 3 in header files is still very common. Do you also need to extern const int width in. h; In. CC, const int width = 5 ;?

This can be done, but it is troublesome. I don't think it is very difficult to define a const int width = 3 in. H. Isn't the compiler doing some special optimization?

Do you also need to allocate a separate space for each unit?

However, the following method can be used to declare a batch of const variables in. h. Note that, unlike common static variables, static member variables of a class are

External links. If

Static const int success = 0; success is not a const but a static int, so it cannot be initialized in the class (compilation error ).

To initialize a. CC file, because it has external links. (In the Google programming specification, it is mentioned that the use of global variables and static members of the class type is forbidden.

Variables are regarded as global variables, and class types are not allowed)

Class Code

{

Public:

Static const result_code success = 0; // program ended successfully

Static const result_code invalid_address = 1; // wrong addres

Static const result_code read_fail = 2; // cannot read

Static const result_code write_fail = 3; // cannot write

Static const result_code unknown_action = 4; // dunno...

Static const result_code not_found = 5; // key not found in paragraph

Static const result_code no_write = 6; // No write Since modification

Static const result_code syntax_err = 7; // command syntax error

Static const result_code empty_clip = 8; // The clipboard is empty

};

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.