}But there is still a question worth thinking about: what is the size of the inventory file? This problem exists theoretically, but most compilers have optimized it. When the same type of a template has multiple instantiated bodies, the compiler will eventually retain only one, this avoids code expansion.
The following is an example:
// Main. cpp
#include "person.h"#include "SmartPointer.h"using namespace std;int test() { //auto_ptr
p(new person("Cici")); //SmartPointer
p(new person("Cici")); //p -> tell(); SmartPointer
r(new person("taoqi")); SmartPointer
p(new person("Cici")); p -> tell(); { SmartPointer
q = p; q -> tell(); r = q; SmartPointer
s(r); s -> tell(); } r -> tell(); return 0;}int main(){ test(); return 0;}
// SmartPointer. h#ifndef SMARTPOINTER_H#define SMARTPOINTER_Htemplate
class SmartPointer{public: SmartPointer(T* ptr); ~SmartPointer(); SmartPointer(SmartPointer
& sptr); T* operator->(); T& operator*(); SmartPointer
& operator=(SmartPointer
& sptr); T getValue();protected: T* ref; unsigned* ref_count;};template
SmartPointer
::SmartPointer(T* ptr){ ref = ptr; ref_count = (unsigned*)malloc(sizeof(unsigned)); *ref_count = 1;}template
SmartPointer
::~SmartPointer(){ --*ref_count; if (*ref_count == 0) { delete ref; free(ref_count); ref = NULL; ref_count = NULL; }}template
SmartPointer
::SmartPointer(SmartPointer
& sptr) { ref = sptr.ref; ref_count = sptr.ref_count; ++(*ref_count);}template
T* SmartPointer
::operator->() { return ref;}template
T& SmartPointer
::operator*() { return *ref;}template
SmartPointer
& SmartPointer
::operator=(SmartPointer
& sptr){ if (this != &sptr) { ref = sptr.ref; ref_count = sptr.ref_count; ++(*ref_count); } return *this;}template
T getValue() { return *ref;}#endif
// Person. h#ifndef PERSON_H#define PERSON_H#include
#include
using namespace std;class person{public: person(string name); ~person(void); void tell();private: string name;};#endif
// Person. cpp#include "person.h"person::person(string name):name(name){}void person::tell(){ cout << "Hi! I am " << name << endl;}person::~person(){ cout << "Bye!" << endl;}
Another article about internal links and external connections:
Http://www.cnblogs.com/magicsoar/p/3840682.html
Internal link and external link
So what are internal and external links?
We know that the declarations and definitions in C ++ can be separated.
For example, in vs, we can place a function Declaration definition in B. cpp. In a. cpp, we only need to declare this function to use it in a. cpp.
A. cpp
void show();int main(){ show();return 0;}
B. cpp
#include
void show(){ std::cout << "Hello" << std::endl;}
Through previous understanding, we know that each compilation unit is independent of each other and does not know the existence of each other.
So how does a. cpp know the definition of the show function?
In fact, when compiling a compilation unit (. cpp) to generate the corresponding obj file
The compiler will analyze this compilation unit (. cpp)
Record the variable definitions of the functions that can be provided to other compilation units (. cpp.
And record the missing functions and variable definitions.
Therefore, we can assume that a. obj and B. obj record the following information:
Then you will know. obj requires the show function definition, while B. obj exactly provides the definition of the show function. Through the link, we can see the running of the show function in the final executable file.
What are the relationships between these external links and internal links?
The compilation units (. cpp) can be compiled to other units (. cpp) display, provide its definition, and let other compilation units (. cpp). variables are external links, such as global variables.
The compilation units (. cpp) cannot be displayed to other compilation units (. cpp) and provide the defined functions. The variables are internal links, such as static functions and inline functions.
Let's take a look at the compilation unit. The internal link and external link are more formal definitions.
Compilation unit: When a c or cpp file is being compiled, the Preprocessor first recursively contains the header file to form a single source file containing all necessary information. This source file is a compilation unit.
Internal Connection: If a name pair is used to compile the unit (. cpp) is local. When linking, other compilation units cannot be linked to it and will not be linked to other compilation units (. the same name in cpp.
External Connection: If a name is not local to the compilation unit (. cpp), other compilation units can access it during the link, that is, it can interact with other compilation units.
Certificate ----------------------------------------------------------------------------------------------------------------------------------------
3. Use the following two methods to prevent repeated include:
# Ifndef PERSON_H
# Define PERSON_H
# Endif
Or
# Pragma once
4. Write the available constants, File Scope constants, and global constants in the definition class:
A. class member variables cannot be initialized when the member variables are defined (unless it is const static). Therefore, the member variable initialization list is the only opportunity for the const variable initialization at this time... Write
Class MyClass {
Private:
Const int a1 = 3;
Const char * s1 = "abc ";
}
It's a big mistake and special mistake !!!! At the same time, note that the initialization can only be performed in the initialization list of the constructor.
B. when defining a global variable, extern int a; is declared and not defined, but extern int a = 3 is defined; of course, it can be defined in. in cpp, extern int a = 3; in B. extern int a; in cpp. However, a more standard approach is to throw extern int a to B. cpp header file B. in h, in B. in cpp, only int a = 3 is defined. When other files are used, only # include "B. h.
C. static const int a = 3; to be written in. cpp, because it is only used in this file. The. h file is for others to include:
Therefore, the correct code is:
// Main. cpp
//main.cpp #include"MyClass.h" #include
using namespace std; int main() { MyClass myClass(30,"abc"); cout << "a2 = " << a2 << endl; cout << "s2 = " << s2 << endl; return 0; }
// MyClass. cpp//MyClass.cpp#include "MyClass.h" #include
using namespace std;const int a2 = 2;const char* const s2 = "s2";static const int a3 = 3;static const char* const s3 = "s3";MyClass::MyClass(const int a = 30, const char* const s = "abc"):a1(a),s1(s){ cout << "a3 = " << a3 << endl; cout << "s3 = " << s3 << endl;}
// MyClass. h//MyClass.h#ifndef MYCLASS_H#define MYCLASS_Hextern const int a2;extern const char* const s2; class MyClass {private: const int a1; const char* const s1;public: MyClass(const int a, const char* const s);};#endif
5. inline functions must be written in the header file:The inline function is characterized by inserting the code of the corresponding function at the place where it is called, so there is no inline function body in the target file after compilation, because it has been replaced by the corresponding statement in the place where it is to be called (of course, this is only limited to the case where inline is successful ).
If we write the inline function in the cpp file, but in most cases, when we use a third-party class library, we only have the header file and the target file (No cpp file ), when you call that inline function, the compiler cannot find it. Therefore, writing inline functions in the cpp file is useless.
6. the last record is the log of initialization of different variables such as const and static:
Http://blog.csdn.net/gljseu/article/details/9750877
1. Common variables: assign values in constructors without considering the efficiency. For efficiency, you can perform this operation in the initialization list of the constructor.Class CA
{
Public:
Int data;
......
Public:
CA ();
......
};
CA: CA (): data (0 )//...... #1 ...... Initialize the list
{
// Data = 0 ;//...... #1 ...... Assignment Method
};
2. static variables:
Static variables belong to all classes but not class objects. Therefore, no matter how many objects the class is instantiated, this variable has only one. In terms of this nature, it is somewhat similar to the uniqueness of global variables.
Class CA
{
Public:
Static int sum;
......
Public:
CA ();
......
};
Int CA: sum = 0 ;//...... #2 ...... Class initialization
3. const constant variable:
The const constant must be initialized upon declaration. Therefore, Initialization is required when a variable is created. It is generally carried out in the initialization list of the constructor.
Class CA
{
Public:
Const int max;
......
Public:
CA ();
......
};
CA: CA (): max (100)
{
......
}
4. Reference variables:
The referenced variable is similar to the const variable. It must be initialized at the time of creation. Also in the initialization list. Note that the Reference type is used.
Class CA
{
Public:
Int init;
Int & counter;
......
Public:
CA ();
......
};
CA: CA (): counter (& init)
{
......
}
5. const static integral variable:
C ++ is privileged for both const and static and integer variables (but different compilers may have different support, which does not seem to be supported by VC 6 ). It can be initialized directly in the class definition. Short works, but float does not.
// For example, the float type can only be initialized outside the class.
// Const float CA: fmin= 3.14;
Class CA
{
Public:
// Static const float fmin = 0.0; // only static const integral data members can be initialized within a class
Const static int nmin = 0;
......
Public:
......
};
To sum up, there are four possible initialization conditions:
1. In the class definition, only the const and static and integral variables are involved.
2. In the class constructor initialization list, including the const object and Reference object.
3. initialized outside the class definition, including static variables. Because it is a unique variable of the class.
4. Common variables can be assigned within the constructor. Of course, this is inefficient.
Class Definition body can only initialize the const integral data type. Put the static type in the. cpp file! Of course, it cannot be placed in member functions. (Static data members can be used for non-static member functions! Static member functions can only call static data members .), Because the static volume is a class, not an object. In this case, every object is used to operate all objects (classes). It is not a mess, so this behavior cannot be allowed.
However, the static value can be assigned to the class constructor. Of course, it cannot be placed in the initialization member list. However, copy construction cannot be used when assigning values in the constructor.Error:
Term does not evaluate to a function taking 1 arguments
The declaration and definition of the static function in the class are as follows:
The declaration of a static function can be declared like a common member function, but a static keyword is added before it.
For example:
Private:
Static int GetXYZ ();
In definition, static keywords cannot be added like static variables. If it is written as follows:
Static int A: GetXYZ ()
{
............
}
The following message is displayed:
'Static 'shoshould not be used on member functions defined at file scope
Therefore, it should be written as follows:
Int A: GetXYZ ()
{// The property of a static function. use other methods to identify it. For example, write this is a static function.
............
}
As for the use of static functions, you can insert them in the code segment you have written as follows:
..................
A: GetXYZ (); // it can be seen that it is A class, not an object
..................
Of course, for the public Type static volume (for example, CString S_str), you can use the following method:
A: S_str = "Hello! ";
CString str = A: S_str;
C ++ member variable initialization problem category: c/c Summary
C ++ provides the class member initialization list for the class.
The construction order of class objects is as follows:
1. allocate memory. when calling the constructor, the data members are initialized implicitly/displayed.
2. After Entering the constructor, execute general calculations in the constructor.
1. Any member variables in the class cannot be initialized during definition.
2. Generally, data members can be initialized in the constructor.
3. the const data member must be initialized in the const initialization list.
4. static should be initialized outside the class definition.
5. array members cannot be initialized in the initialization list.
6. You cannot specify an Explicit initialization for the array.
These six items indicate a problem: the constant array cannot be defined in C ++! Because of the conflict between 3 and 5. Can't this happen? No way, I had to turn to static data members.
At this point, my problem is solved. But I also want to take the opportunity to review C ++ class initialization:
1. Initialization list: CSomeClass (): x (0), y (1 ){}
2. Out-of-class initialization: int CSomeClass: myVar = 3;
3. the const constant definition must be initialized, and the initialization list should be used in the C ++ class;
4. The C ++ class cannot define a constant array.