C ++ declarations, definitions, class definitions, and header file functions to prevent repeated reference of header files in the same compilation unit, without being named

Source: Internet
Author: User

1. compile unit, A. cc, or. cpp as a compilation unit. Generate. o

2. Definitions, declarations, and function definitions of common data types (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 definitions 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 the print function definition. Otherwise, the compiler reports an error if it finds that the program uses x and print. If a statement is not defined, an error is returned during the link.
I call print () in source. cc, while print () is declared in head. h, and include in source. cc.
Head. h has the print statement, which can be compiled. However, if no print function is defined in all compilation units

An error occurs when the source. o unit is connected, 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, multiple repeated declarations can exist.
// 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 definition of common variables is not allowed by the function definition.

3. Duplicate symbols within the same compilation unit are blocked during the compilation period. The duplicate symbols between different compilation units must be sent to the linker.

Now.

If you are in a source1.cc

// Source1.cc

Int x;

Int x;

If int x or int x is returned twice, an error is reported during compilation and the definition of x is repeated.

If your

// Source1.cc

Int x;

// Source2.cc

Int x;

G ++-o test source1.cc source2.cc

There will be no errors in the compilation process. In the link process, because the target code contains two fully-local x, the link will fail and x will be redefined.

Different programmers may write different modules, so this is very likely to happen. How can we avoid it? namespace can avoid duplicate names.

Non-namespace is encouraged in google programming specifications

// 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, this simple example is only available in source1.cc with an anonymous namespace.

Avoid link travel.

// Note

// 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. 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.

 

Differences between static and anonymouse namespace in C ++
| Category: Desktop Application Development
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 a local persistence (which is my goal). Then someone said why I didn't use static, well, it seems that there is no difference between the two things at first glance. I Google it and found that the member in anonymousenamespace has external links, it cannot be accessed by external links! Static makes it clear that there is no external link at all! In this case, a problem occurs. In the template, non-type parameters 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 anon namespace because the static method is criticized by the C ++ 98 standard. In general, you can use anony namespace instead of static.

 

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.

Therefore, if

G ++-o test source1.cc source2.cc will also find the repeatedly defined global variable x During the chain.

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 my head. h is written as follows, does it prevent redefinition errors during the link of x?

// 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.

That is to say, to prevent possible

// 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 be sent

// 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 still references head. h, even if # ifndef # endif exists.

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 and multiple compilation units.

Class {

}; // Class definition www.2cto.com

The definition of the class is a little special. You may wonder why you cannot put int x; such a variable definition in. h (see figure 4), but you can

What if the class definition is repeatedly referenced in the header file? At the same time, functions of the class are not defined by inline (except for those written in the class definition) and cannot be written in

Header file.

This is because the definition of the class only tells the compiler how the data format of the class is, and the object after the instance occupies much space.

Class definition does not generate the target code. Therefore, the only difference between it and the declaration of common variables is that it 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 will be produced in this compilation unit.

// If class A {}; is defined in head. h, but head. h does not

// # Ifndef # endif indicates that compilation errors of repeated classes may occur in the same compilation unit.

 

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!

// Source1.cc

Class {

}

// Source2.cc

Class {

Int x;

} // Different compilation units, OK

 

6. Summary

1. Write the declaration of variables, function declaration, class definition, and inline function in the header file. do not define variables. Functions of the class are not defined by inline.

.

That is to say, do not display any stuff that may generate the target code in the header file.

2. To prevent repeated references from header files in a compilation unit, # ifndef # endif must be added to all header files.

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

4. For more professional details, see chapter 1 of <large-scale C ++ Program Design>.

The class definition has the internal link feature, that is, it is not a declaration.

It cannot be repeated in the same compilation unit, but it has internal links, the link is not the same as that in other compilation units.

), So if the class is to be used outside a single compilation unit, it must be defined in a header file.

For the Declaration and definition, the definition in the book is:

A declaration introduces a name to 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 mentioned above is not very accurate. According to the statement in <large-scale C ++ Program Design>

Theoretically, the header file can contain all the items with internal links, including definitions with internal links. For example

Static int x;

Static void print (){};

However, this is not recommended because every header file that contains this header file. cc corresponds to opening up a space to store the x, that is, static int x is introduced to different compilation units. Because it is an internal link, it does not affect each other.

Even if you use namespace

In. h

Namespace myspace {

Static int x;

}

This header file is introduced in different. cc files, and the myspace: x called in the respective compilation unit is different from each other!

As mentioned in the book

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

This const variable should also be avoided in the header file, but similar to the previous C Language

In the header file

# Define width 3

It is still very common. Is it necessary

. H

Extern const int width;

. Cc in progress

Const int width = 5;

This is acceptable, but it is troublesome. the definition in h is similar to const int width = 3. Isn't the compiler doing some special optimization? Is it necessary 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 normal static variables, static functions have 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), and must be in. cc file, because it has external links. (In GOOGLE programming specifications, global variables of the class type are prohibited. static member variables are regarded as global variables, and class types are also prohibited)

 

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

};

 

From XpowerLord
 

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.