Original http://blog.csdn.net/ithzhang/article/details/8119286
ThemeC + + C + + has been studying for years you know why when you define a class, the definition of the class is placed in the. h file, and the implementation of the class is placed in the CPP file. Why can they be linked together? You know what can be put in the. h file and what can't. What can be placed in the CPP file again. If you forget or do not understand, then read this article you will be very clear!! The difference between a statement and a definition is first discussed.
A declaration is the introduction of a name into a program. A definition provides a unique description of an entity in a program. declarations and definitions are sometimes present at the same time.
such as int A;
extern int b=1;
The declaration is only if the initializer does not exist in extern. Other situations are both definitions and declarations.
However, in the following cases, the declaration is merely a declaration:
1: Only provide function prototypes. such as void Func (Int,int);
2:extern int A;
3:class A;
4:typedef statement
5: Declaration of a static data member defined in a class
Such as:
a{public : int A; Statement. };
The definition is only defined in the following cases:
1: Define and initialize a static data member outside of the class definition. such as a::a=0;
2: Define non-inline member functions outside the class.
A declaration simply introduces a symbol to a scope. The definition provides a unique description of an entity in the program. It is possible to declare a symbol repeatedly in a given definition field, but it cannot be defined repeatedly, or it will cause a compilation error. However, member functions and static data members in a class are exceptions, although within a class they are declarations, but they cannot have more than one.
Such as:
a{public : void func (int,void func (int,int);};
Understand the difference between declaration and definition, but also need to understand the internal links, external links. Only when you understand them will you know the questions raised at the beginning.
At compile time, the compiler detects only program syntax and functions, and whether variables are declared. If the function is not declared, the compiler will give a warning, but the target file can be generated. When linking a program, the linker will look for the implementation of the function in all the target files. If you cannot find it, you will be reported with the link error code (Linker error). In VC, this error is generally: Link 2001 error, meaning that the linker could not find the implementation of the function.
Links relate the symbols generated by different compilation units. There are two ways to link: internal links and external links.
If a symbol name is local to its compilation unit and is not likely to conflict with the same name in other compilation units at the time of the link, the symbol is an internal link. An internal link means that access to this symbol is limited to the current compilation unit and is not visible to other compilation units.
Static global variables are represented when the static keyword is acting on a global variable. But the scope is only within the scope of the current file. Other files cannot be used even if the extern declaration is used. Const is similar.
Connections with the static, const keyword, and enumeration types are internal.
Symbols with internal links cannot be used outside the current file, and you can place them in an. h file if you want them to affect other parts of your program. At this point, all the source files that contain this. h file have their own definitions and do not affect each other.
The definition of a class has an internal link, because it is defined and therefore cannot be repeated in the same compilation unit. If you need to use it in other compilation units, the class must be defined in the header file and contained by other files. Use Class A only in other files; The declaration is not possible because the definition of the class is an internal link and does not export the symbol in the destination file. They will not be parsed by other units for their undefined symbols. It is important to understand this point.
Inline functions also have internal links.
In a multi-file program, if a symbol can interact with other compilation units at link time, then the name has an external link. An external link means that the definition is not confined to a single compilation unit. It can produce external symbols in the. o file. can be accessed by other compilation units to parse symbols that they do not define. Therefore, they must be unique throughout the program, or they will result in a duplicate definition.
Non-inline member functions, non-inline functions, and non-static free functions all have external links.
All of the inline functions have internal links, because the compiler, when possible, replaces all calls to functions with the body of the function, without writing any symbols to the. o file.
A good way to determine whether a symbol is an internal link or an external link is to see if the symbol is written to the. o file.
What I said earlier was the impact of the definition on how the link was linked, and then the implications of the Declaration on how to link it.
Because the declaration is only useful for the current compilation unit, the declaration does not write anything to the. o file.
such as extern int A;
int func ();
These statements themselves do not affect the contents of the. o file. Each one is simply naming an external symbol so that the current compilation unit can access the corresponding global definition when needed.
A function call causes an undefined symbol to be written to the. o file. If a is not used in the file, it is not written to the. o file. The Func function has a call to this function. This symbol is also written to the destination file. Thereafter this. o file is concatenated with the. o file that defines this symbol, and the previously undefined symbol is parsed.
The above declaration may cause the symbol to be written to the destination file. However, the following declaration does not cause the symbol to be written to the destination file.
Such as:
typedef int INT;A; S Point ;
Their links are also internal.
Both the class declaration and the class definition are internal links. is used only for the current compilation unit.
Static class data members have external links. Such as
static int A;} ;
Static data member A is merely a declaration, but its definition is a::a=0; But with external links.
C + + has a different way of handling classes and enumeration types. For example, you can declare a class when you do not define a class. However, an enumeration type cannot be declared without definition.
Based on the above analysis, we can see that the definition of having external links in the header file is almost a programming error. Because if the header file is contained in more than one source file, there will be more than one definition, and the link will be error-prone.
The definition of placing an internal link in a header file is legal, but not recommended. Because header files are included in multiple source files, not only does it pollute the global namespace, but it also has its own entity in each compilation unit. A large amount of memory space consumption can also affect machine performance.
The const and static modified global variables are only valid within the scope of the current file. They have internal link properties.
The following is a list of some definitions that should or should not be written to the header file:
Test.h#ifndef Test_h#Define Test_hint A;A has external links and cannot be defined in the header file.externint b=10;Ditto.Constint c=2;C has internal links that can be fixed in the header file but should be avoided.Staticint d=3; //ibid. static void func () {} //ibid. void func2 () {} //with a. void func3 (); //can. Just a statement. does not cause the symbol name to be written to the destination file. class a{public: static int e; //Yes, with internal links. int f;//can, ibid. void func4 (); //statement, internal link. Ditto. }; A::e=10; You cannot include a definition with external links in the header file. The symbol name is not written to the destination file. void a:func4 () //can not, class member function. External connections. {//,......} #endif
I believe you now understand why it is legal to declare member functions only in a type, and not to implement it. You can also answer why the definition of a class can be placed in an. h file. The implementation of the class can be placed in a CPP file of the same name. The teacher's previous introduction is that the compiler will automatically look for CPP files with the same name. In fact, because the CPP file is stored in the implementation of member functions, and member functions have external link characteristics, the target file will produce symbols. This symbol is defined in this file. Other target files that call this member function will also produce an undefined symbol. This symbol is parsed after the two target files are connected. Note the static data member should be placed in the CPP file. and cannot be placed in the. h file.
A definition with an internal link can be defined in a CPP file without affecting the global symbolic space. However, in the CPP file scope, you want to avoid defining (and not prohibiting) data and functions that are not declared as static. Because they have external links.
Such as
int A; void func () { ...}
The above definitions have external links that may potentially conflict with other symbolic names of the global namespace. Because inline functions and static free functions, enumerations, and data of const types have internal links, they can be defined in a CPP file without affecting the global namespace.
typedef and macro definitions do not introduce symbols into. o files, which can also appear in CPP files without affecting the global namespace.
The typedef creates an alias for an existing type. Instead of creating a new type. It does not provide type safety. Such as
int IntA;int InB;
The use of IntB in places where IntA is required will not be an error. They can be replaced with each other. Because of this we call it not to provide type safety. However, a typedef is often used when defining a function type to make the definition clearer.
The standard C library provides an Assert macro that guarantees that the given expression value is nonzero. Otherwise, the error message is output and the program execution is terminated. An assert will only work if NDEBUG is not defined in the program. Once the ndebug is defined, the Assert statement is ignored. Note the difference from the ASSERT in the VC. The assert is provided by the VC. It only works when _DEBUG is defined.
In the VC DEBUG mode _DEBUG will be defined. In RELEASE mode, Ndebug is defined.
Well, I'm sure everyone will understand the questions raised at the beginning. If you do not understand, please be sure to leave a message oh. If there is any mistake, please do not hesitate to correct me!!
The above content is referenced from the Large scale C + + software design.
C + + has been studying for so many years that you may not know why class definitions are placed in the. h file, class implementations placed in the CPP file. How do they relate?