C++ must master knowledge points

C++ must master knowledge points

1. New, delete, malloc, free relationship
delete will call the destructor of the object, corresponding to new, free will only release the memory, and new will call the constructor. malloc and free are standard library functions of C++/C language, and new/delete are operators of C++. They can be used to apply for dynamic memory and release memory. For objects of non-internal data types, using maloc/free alone cannot meet the requirements of dynamic objects. The object must automatically execute the constructor when it is created, and the object must automatically execute the destructor before it dies. Since malloc/free is a library function rather than an operator, it is not within the control authority of the compiler, and the task of executing the constructor and destructor cannot be imposed on malloc/free. Therefore, the C++ language needs an operator new that can complete dynamic memory allocation and initialization, and an operator delete that can complete cleanup and release memory. Note that new/delete are not library functions.
2. The difference between delete and delete []
delete will only call the destructor once, and delete [] will call the destructor of each member. There is a more detailed explanation in More Effective C++: "When the delete operator is used on an array, it calls the destructor for each array element, and then calls operator delete to release the memory." delete is matched with new, delete [] Matching with new []
For built-in simple data types, delete and delete [] functions are the same. For custom complex data types, delete and delete[] cannot be used interchangeably. delete[] deletes an array, and delete deletes a pointer. Simply put, memory allocated with new is deleted with delete; memory allocated with new[] is deleted with delete[].
3. What are the properties of C++ (object-oriented features)
encapsulation, inheritance and polymorphism.
4. Should the destructor of the parent class be called when the subclass is destructed?
The order in which the destructor is called is the destructing of the derived class first and then the destructing of the base class, that is to say, when the destructing of the base class is called, all the information of the derived class has been destroyed. When defining an object, the constructor of the base class is called first, and then the constructor of the derived class is called; when it is destructed, it is just the opposite: the destructor of the derived class is called first, and then the destructor of the base class is called.
5. Polymorphism, virtual function, pure virtual function
Polymorphism classification:
Polymorphism can be divided into static polymorphism and dynamic polymorphism. Static polymorphism includes function overloading and generic programming; dynamic polymorphism is mainly reflected in virtual functions.

Early binding and late binding:
(1) The C++ compiler will determine the address of each object calling function (non-virtual function) when compiling, which is called early binding (also called static binding) (2)
When we When a function is declared as virtual, the compiler will not determine the address of the function to be called by the object at compile time, but will determine the address of the function to be called at runtime. This is late binding (also called dynamic binding )
Polymorphism: Different actions are generated when different objects receive the same message. The polymorphism of C++ is embodied in two aspects: running and compiling: the polymorphism at program runtime is reflected through inheritance and virtual functions;
what happens behind virtual?
(1) When the compiler is compiling, it finds that there are virtual functions in the Father class. At this time, the compiler will create a virtual table (vtable) for each class containing virtual functions. The table is a one-dimensional array. In this The address of each virtual function is stored in the array.
(2) So how to locate the virtual table? The compiler also provides a virtual table pointer (vptr) for each object, which points to the virtual table of the class to which the object belongs.
(3) When the program is running, vptr is initialized according to the type of the object, so that vptr correctly points to the virtual table of the class to which it belongs, so that the correct function can be found when calling the virtual function.
(4) Since the virtual function called by each object is indexed by the virtual table pointer, it is decided that we cannot call the virtual function before the virtual table pointer is not properly initialized.
(5) So where is the virtual table pointer initialized? The virtual table is created and the virtual table pointer is initialized in the constructor. When constructing a subclass object, the constructor of the parent class must be called first. At this time, the compiler only "sees" the parent class and does not know whether there is an inheritor behind it. It initializes the virtual table pointer of the parent class object. The table pointer points to the virtual table of the parent class. When the constructor of the subclass is executed, the virtual table pointer of the subclass object is initialized to point to its own virtual table.

Polymorphism summary
(1) Polymorphism in C++ is realized through late binding (dynamic binding) technology
(2) Classes containing virtual functions have virtual tables
(3) When a subclass does not duplicate the virtual functions of the parent class When writing, the virtual table pointer of the subclass saves the virtual table of the parent class; when the subclass rewrites the virtual table of the parent class, the virtual table pointer of the subclass saves the virtual table of the subclass; When you have your own virtual function, add the address of this virtual function in the virtual table.
If you still don’t understand the specific principles of polymorphism, you can refer to the original link (it’s very classic): https://blog.csdn.net/weixin_38952721/article/details/100130983

Polymorphism is reflected in the overloading of functions and operators when the program is compiled;
virtual function: a member function with the keyword virtual in the base class. It provides an interface interface. Allows redefinition of base class virtual functions in derived classes.
The role of pure virtual function: Reserve a function name for its derived class in the base class, so that the derived class can define it as needed. As an interface, a pure virtual function does not have the function of a function, and generally cannot be called directly.
A pure virtual function inherited from a base class is still a virtual function in a derived class. If a class has at least one pure virtual function, then this class is called an abstract class (abstract class).
Abstract classes include not only pure virtual functions, but also virtual functions. An abstract class must be used as a base class from which other classes are derived, and cannot be used to directly create object instances. However, runtime polymorphism is still supported using pointers to abstract classes.

x&(x-1) counts the number of 1, x|(x+1) counts the number of 0

7. What is a "reference"? What issues should be paid attention to when declaring and using "reference"?
Answer: A reference is an "alias" (alias) of a target variable, and the operation on the application is exactly the same as the direct operation on the variable. When declaring a reference, remember to initialize it. After the reference is declared, it means that the target variable name has two names, that is, the original name of the target and the reference name, and the reference name cannot be used as an alias of other variable names. Declaring a reference does not define a new variable, it only means that the reference name is an alias of the target variable name, it is not a data type itself, so the reference itself does not occupy a storage unit, and the system does not allocate storage units for the reference. A reference to an array cannot be created.
8. What are the characteristics of using "reference" as a function parameter?
(1) Passing a reference to a function has the same effect as passing a pointer. At this time, the formal parameter of the called function is used as an alias of the actual parameter variable or object in the original calling function, so the operation on the formal parameter variable in the called function is the corresponding target object (in the main calling function) Call function) operation.
(2) The parameters of the function are passed by reference, and no copy of the actual parameter is generated in the memory, it is directly operated on the actual parameter; while the parameters of the function are passed by the general variable, when the function call occurs, storage needs to be allocated to the formal parameter Unit, the formal parameter variable is a copy of the actual parameter variable; if an object is passed, the copy constructor will also be called. Therefore, when the data passed by the parameter is large, the efficiency and space occupied by the reference are better than that of the general variable.
(3) Although using a pointer as a function parameter can also achieve the effect of using a reference, in the called function, the storage unit must also be allocated to the formal parameter, and the operation in the form of "*pointer variable name" needs to be repeated. This is prone to errors and the readability of the program is poor; on the other hand, at the calling point of the calling function, the address of the variable must be used as an actual parameter. References, on the other hand, are easier to use and clearer.
9. When do you need to use "constant references"? 
If you want to use references to improve the efficiency of the program and protect the data passed to the function from being changed in the function, you should use constant references. Constant reference declaration method: const type identifier & reference name = target variable name; reference parameters should be defined as const as much as possible if they can be defined as const.
10. What are the format, benefits and rules to be followed when using "reference" as the return value type of a function?

Format: type identifier & function name (formal parameter list and type description) { //function body}
Benefits: no copy of the returned value is generated in memory; (note: it is for this reason that a local variable is returned The reference of is not advisable. Because with the end of the lifetime of the local variable, the corresponding reference will also become invalid, resulting in runtime error! Note: (1
)
The reference of the local variable cannot be returned. This article can refer to Effective C++[1 ]’s Item 31. The main reason is that the local variable will be destroyed after the function returns, so the returned reference becomes a "nothing" reference, and the program will enter an unknown state. (2) Cannot return the function allocated by
new Reference to memory. This article can refer to Item 31 of Effective C++ [1]. Although there is no passive destruction of local variables, there are other embarrassing situations in this case (returning a reference to memory allocated by new inside the function). For example , the reference returned by the function only appears as a temporary variable without being assigned an actual variable, then the space pointed to by this reference (allocated by new) cannot be released, resulting in memory leak. (3) Can return class
members Reference, but preferably const. This principle can refer to Item 30 of Effective C++ [1]. The main reason is that when the attribute of an object is associated with a certain business rule (business rule), its assignment is often related to some It is related to other properties or the state of the object, so it is necessary to encapsulate the assignment operation in a business rule. If other objects can obtain a non-constant reference (or pointer) to the property, then the simple assignment of the property will break the business rule. integrity.

What is the use of const There are
three main points:
1: Define read-only variables, that is, constants
2: Modify the parameters of the function and the return value of the function
3: Modify the definition body of the function, where the function is a member function of the class, a member modified by const Function representatives do not modify the value of member variables

The difference between a pointer and a reference
1: A reference is an alias of a variable, and the internal implementation is a read-only pointer
2: A reference can only be assigned a value at initialization, and the value cannot be changed at other times, and the value of the pointer can be changed at any time
3: Reference Can not be NULL, the pointer can be NULL
4: The reference variable memory unit saves the address of the referenced variable
5: "sizeof reference" = the size of the pointed variable, "sizeof pointer" = the size of the pointer itself
6: The reference can take the address operation , what is returned is the address of the memory unit
where the referenced variable itself is located.

Compare and analyze several common containers such as map, vector, and list.
List sequential container supports fast insertion and deletion, but takes time to search;
Vector sequential container supports fast search, but inserts time-consuming.
Map is an associative container, map is a mapping from key (key) to value (value), the key value is unique, and the time complexity of searching is logarithmic, which is almost the fastest, and hash is also logarithmic.

Summary of references
  (1) In the use of references, it is meaningless to simply give a variable an alias. The purpose of references is mainly used in the transfer of function parameters to solve the problem of unsatisfactory transfer efficiency and space of large blocks of data or objects question.
  (2) Passing the parameters of the function by reference can ensure that no copy is generated during the parameter transfer, which improves the efficiency of the transfer, and through the use of const, the security of the reference transfer is guaranteed.
  (3) The difference between a reference and a pointer is that after a pointer points to an object through a pointer variable, it indirectly operates on the variable it points to. If pointers are used in the program, the readability of the program is poor; and the reference itself is an alias of the target variable, and the operation on the reference is the operation on the target variable.
  (4) When to use references. Stream operators << and >>, the return value of the assignment operator =, the parameters of the copy constructor, the parameters of the assignment operator =, and other situations are recommended to use references.
11. What is the difference between structure and union?

(1). Both the structure and the union are composed of multiple members of different data types, but at any one time, only one selected member is stored in the union (all members share one address space), while all members of the structure are Exist (the storage addresses of different members are different).
(2). Assignment to different members of the union will overwrite other members, and the value of the original member will no longer exist, and assignment to different members of the structure will not affect each other.

13. What is the difference between overload and overried (some books are also called "coverage")?
Frequently asked questions. From the definition:
Overloading: It means that multiple functions with the same name are allowed, and the parameter tables of these functions are different (maybe the number of parameters is different, maybe the parameter types are different, maybe both are different).
Overriding: refers to the method by which a subclass redefines the virtual function of the parent class.
In terms of implementation principles:
Overloading: The compiler modifies the names of functions with the same name according to the different parameter tables of the functions, and then these functions with the same name become different functions (at least for the compiler). For example, there are two functions with the same name: function func(p:integer):integer; and function func(p:string):integer;. Then the function name modified by the compiler may be like this: int_func, str_func. The calls to these two functions have been determined between compilers and are static. In other words, their addresses are bound at compile time (early binding), so overloading and polymorphism have nothing to do!
Rewriting: Really related to polymorphism. When the subclass redefines the virtual function of the parent class, the parent class pointer dynamically calls the function belonging to the subclass according to the different subclass pointers assigned to it. Such a function call cannot be determined during compilation (call The address of the virtual function of the subclass cannot be given). Therefore, such function addresses are bound at runtime (late binding).
14. In which cases can only the initialization list be used instead of the constructor?
Answer: When the class contains const-limited constant members and member variables are reference types, the initialization list is required.
15. Is C++ type safe?
Answer: no. Between two different types of pointers can be cast (with reinterpret cast). C# is type safe.
16. Before the main function is executed, what code will be executed?
Answer: The constructor of the global object will be executed before the main function.
17. Describe the memory allocation methods and their differences?
The memory occupied by a program compiled by c/C++ is divided into the following parts:
1. Stack area (stack) - automatically allocated and released by the compiler, storing function parameter values, local variable values, etc. It operates like a stack in a data structure.
2. Heap area (heap) - generally allocated and released by the programmer, if the programmer does not release it, it may be recycled by the OS at the end of the program.
Note that it is different from the heap in the data structure, and the allocation method is similar to a linked list, haha.
3. Global area (static area) (static) - the storage of global variables and static variables is put together,
initialized global variables and static variables are in the same area, uninitialized global variables and uninitialized static variables are in the same area another adjacent area. - It will be released by the system after the program ends
4. Literal constant area - the constant string is placed here. Released by the system after the program ends.
5. Program code area - store the binary code of the function body.

18. Write out the comparison statements between variable a of BOOL, int, float and pointer type and "zero".
Answers:
BOOL : if ( !a ) or if(a)
int : if ( a == 0)
float : const EXPRESSION EXP = 0.000001
if ( a < EXP && a >-EXP)
pointer : if ( a != NULL) or if(a == NULL)
19. Please tell me what are the advantages of const compared with #define?
Answer:
The role of const: defining constants, modifying function parameters, and modifying function return values. Things modified by Const are subject to mandatory protection, which can prevent accidental changes and improve the robustness of the program.
1) const constants have data types, but macro constants do not have data types. The compiler can perform type safety checks on the former. For the latter, only character replacement is performed, without type safety checks, and unexpected errors may occur during character replacement.
2) Some integrated debugging tools can debug const constants, but cannot debug macro constants.
20. Briefly describe the difference between arrays and pointers?
Arrays are created either in static storage (like global arrays) or on the stack. A pointer can point to any type of memory block at any time.
(1) Differences in modified content
char a[] = "hello";
a[0] = 'X';
char *p = "world"; // note that p points to a constant string
p[0] = 'X' ; // Compiler can't catch the error, runtime error
(2) Use the operator sizeof to calculate the capacity (number of bytes) of the array. sizeof§,p gets the number of bytes of a pointer variable for a pointer, not the memory capacity pointed to by p. The C++/C language has no way to know the memory capacity pointed to by the pointer, unless it is remembered when applying for memory. Note that when an array is passed as an argument to a function, the array automatically degenerates into a pointer of the same type.
char a[] = "hello world";
char *p = a;
cout<< sizeof(a) << endl; // 12 bytes
cout<< sizeof§ << endl; // 4 bytes
count array and pointer void
Func(char a[100])
{ cout<< sizeof(a) << endl; // 4 bytes instead of 100 bytes } Question 21: Int (*s[10])(int) means What is it? int (*s[10])(int) Array of function pointers, each pointer points to a function of int func(int param). Question 25: What is the difference between a reference and a pointer?




[reference answer]

  1. References must be initialized, pointers do not.
  2. The reference cannot be changed after initialization, and the pointer can change the object it points to.
  3. There are no references to null values, but there are pointers to null values.
    Question 26: Compared with const and #define, what are the advantages of const?

[Reference answer]
(1) const constants have data types, but macro constants have no data types. The compiler can perform type safety checks on the former. For the latter, only character substitution is performed without type safety checks, and unexpected errors (marginal effects) may occur during character substitution.
(2) Some integrated debugging tools can debug const constants, but cannot debug macro constants.
Question 29: The destructor of the base class is not a virtual function, what problems will it cause?
[Reference answer] The destructor of the derived class cannot be used, which will cause resource leakage.
30 Questions: What is the difference between global variables and local variables? How is it achieved? How do the OS and compiler know?
[Reference answer]
The life cycle is different:
global variables are created and created with the main program, and destroyed with the destruction of the main program; local variables exist inside local functions, even local loop bodies, etc., and exit does not exist; different ways of use: by
declaring All parts of the post-global variable program can be used; local variables can only be used locally; allocated in the stack area.
Known to the operating system and compiler by the location of the memory allocation, global variables are allocated in the global data segment and loaded when the program starts running. Local variables are allocated on the stack.
people must rely on themselves

atoi
  C language library function name: atoi
  function: convert a string into an integer
itoa
function function: convert an integer into a string

Functions of constructors and destructors:
Constructors: Generally speaking, in a class, a function whose function name is the same as the class name is called a constructor. Its function is to do some initialization work (such as assigning initial values ​​to data) when creating an object. C++ allows functions with the same name, which also allows multiple constructors in a class. If neither is present, the compiler will generate a default constructor for the class.

Destructor: When an object of a class leaves the scope, the destructor will be called (automatically called by the system). The name of the destructor is the same as the class name, but preceded by ~. For a class, only one destructor is allowed, the destructor cannot have parameters, and there is no return value. The role of the destructor is to complete a cleanup work, such as releasing the memory allocated from the heap.
A class can have multiple constructors, but only one destructor. The order in which objects are destructed is the reverse of the order in which they were created, that is, objects constructed later are destructed first.

The string array strstr for substring search
  returns the address of the first character of the substring in the string to be searched. Returns a null pointer if the substring does not exist.

The find method of the string string for substring search
The find function in the string header file is to find the index of the substring in the main string.

What is the use of const There are
three main points:
1: Define read-only variables, that is, constants
2: Modify the parameters of the function and the return value of the function
3: Modify the definition body of the function, where the function is a member function of the class, a member modified by const Function representatives do not modify the value of member variables
How to avoid memory leaks

  1. Summarized a lot of rules: use in pairs, ensure that malloc/new and free/delete match, free memory pointers should be empty, apply and release memory in as few functions as possible, etc.
  2. It is also a way to replace the method of manually allocating object memory with the dynamic array of STL components;

Under what circumstances will the system call the copy constructor: (three cases)
(1) When an object of the class is used to initialize another object
(2) When the formal parameter of the function is an object of the class (that is, when the value is passed) , if it is passed by reference, it will not be called
(3) When the return value of the function is an object or reference of the class

After a pointer is free, it must be empty, otherwise a wild pointer will be generated, and an error will occur if it is called accidentally.

sizeof () and strlen ()
1. sizeof
sizeof (…) is an operator. In the header file, typedef is unsigned int, and its value is calculated at compile time. The parameters can be arrays, pointers, types, objects, functions, etc. .
Its function is to obtain the byte size guaranteed to accommodate the largest object created by the implementation.
Since it is calculated at compile time, sizeof cannot be used to return the size of a dynamically allocated memory space. In fact, use sizeof to return the type and the space occupied by the statically allocated object, structure or array, and the return value has nothing to do with the content stored in the object, structure, or array.
2. strlen
strlen(...) is a function that can only be calculated at runtime. The parameter must be a character pointer (char*). When the array name is passed in as a parameter, the array actually degenerates into a pointer.
Its function is: return the length of the string. The string may be defined by itself, or it may be random in the memory. The function actually completed by this function is to traverse from the first address representing the string until it encounters the terminator NULL. The returned length size does not include NULL. char str[20]="0123456789";
int a1=strlen(str); //a=10;
int b1=sizeof(str); //and b=20;

char str1[]="0123456789";
int a2=strlen(str1); //a=10;
int b2=sizeof(str1); //而b=11;

char *str3="0123456789";
int a3=strlen(str3); //a=10;
int b3=sizeof(str3); //而b=4;

Shallow copy and deep copy
Shallow copy: The default copy constructor of the system, only the default copy constructor, copies the values ​​of non-static members one by one (the copying of members becomes shallow copying), and the values ​​of members are copied, and multiple members of the same class Objects have the same memory layout but different addresses, so they are copied directly.
Deep copy: Pointer members cannot be assigned directly, but memory copy, memcpy, strcpyd, etc. To put it
simply, in the case of pointers, shallow copy just adds a pointer to the existing memory, while deep copy adds a Pointer and apply for a new memory, so that the added pointer points to this new memory. In the case of deep copy, when the memory is released, the error of repeatedly releasing the same memory during shallow copy will not appear!

The difference between Inline and #define:

  1. A macro is a simple replacement without any verification at the code, while an inline function inserts the code directly into the call site, reducing the resource consumption of ordinary function calls.
  2. A macro is not a function, it just replaces the relevant character strings in the program with the macro body in the preprocessing stage before compiling.
  3. inline is a function, but the code is not generated separately during compilation, but the relevant code is embedded into the calling site.
    The summary is as follows:
      For general constants, it is best to replace #define with const and enum;
      for macros similar to functions, it is best to replace #define with inline functions.

Virtual destructor
In polymorphism, if you release the parent class pointer, only the destructor of the parent class will be called, so if virtual destructor is added, both the subclass and the parent class will be called. The destructor of which type of pointer is deleted will be called
Base* p1 = new Derived; // The pointer of the parent class points to the object of the subclass
delete p1;
because the destructor of the subclass overrides the destructor of the parent class function, although the destructor names of the subclass and the parent class are different, the
compiler does special processing for the destructor, and the destructor names of the subclass and the parent class are the same internally.
Therefore, if the destructor of the parent class is not defined as a virtual function, it does not constitute polymorphism. Since the destructor of the parent class hides the destructor of the subclass, it can only be transferred to the destructor of the parent class.
However, if the destructor of the parent class is defined as a virtual function, then the destructor of the subclass will be called directly when calling.
Since the subclass is destructed first, the parent class must be destructed, and the subclass is destructed. Both the subclass and the inherited parent class are destructed

What is MVC (Model View Controller)?
MVC is an architectural pattern that separates presentation from interaction. It is divided into three core components: Model, View, and Controller. The following is the division of labor for each component:
• The view is the interface that the user sees and interacts with.
• Models represent business data and provide data to views.
• The controller accepts user input and invokes models and views to fulfill the user's needs.

Control flow of MVC (Model, View, Controller) architecture:
• All end-user requests are sent to the controller.
• The controller relies on the request to select which model to load and attach the model to the corresponding view.
• The final view with model data appended is sent in response to the end user.

Advantages and disadvantages of MVC:
advantages, high portability, easy to change, clear code logic, disadvantages, lower operating efficiency

C++ design pattern:
Simple factory pattern
The factory pattern has a very vivid description. The class that creates objects is like a factory, and the objects that need to be created are products one by one; the people who process the products in the factory and use the products don’t care about the products. how it was produced.
Usage scenario:
When you are not sure how many processing operations there will be, you should consider using the simple factory pattern. For example, for the same received data, the processing logic may be different, and new operations may be added in the future.
Case:
If the function of a calculator is implemented, for the same input data, addition, subtraction, multiplication, division, and even other functions may be performed. Therefore, an abstract class or interface of an operation can be abstracted, a unified processing method (process here) can be provided, and a subclass can be created for each operation. The judgment of which specific implementation class to use is made in the factory class (the variable that stores the operation is passed to the production method of the factory). The factory class always returns this abstract class, so that if the original function is changed or new functions are added, other original classes will not be modified, and only the modified class or new class can be compiled up.
This minimizes coupling and facilitates maintenance.

Simple factory: for the same data, different operations use the same interface
Factory method: for the same data, different operations use different interfaces
Abstract factory: for different data, different operations use different interfaces

Singleton mode: Singleton mode ensures that there is only one instance of a certain class, and it instantiates itself and provides this instance to the entire system. model)

Observer mode: defines a one-to-many dependency relationship, allowing multiple observer objects to monitor a certain subject object at the same time. This subject object notifies all observer objects when there is a change in state, enabling them to update themselves automatically. (The signal mechanism of QT and the message mechanism of Windows all apply the observer mode, as well as subscribe to emails, and emails will be sent to you when the emails arrive)

Builder mode: The internal appearance of the product can be changed independently, and the customer does not need to know the details of the internal composition of the product. A step-by-step construction process can be enforced. To use one interface to complete different operations, it is necessary to grasp the needs of customers. (For example: log in to QQ, automatically select the server where you are located)

Command mode: separate the responsibility of issuing commands from the responsibility of executing commands, assigning to different objects allows the requesting party and the sending party to be separated, so that the requesting party does not need to know the interface of the receiving party, let alone the request How it was received, and whether, when and how the operation was performed. (The command mode is used most between the client and the server (C/S architecture))

wait wait ==

单例模式实现:
#include <stdio.h>
#include <stdlib.h>
#include
using namespace std;
class CFather
{
public:
static bool nFlag;
protected:
private:
CFather()
{
}
~CFather()
{
nFlag = true;
}
public:
static CFather * CreatObject()
{
if (nFlag)
{
nFlag = false;
return (new CFather);
}
else
{
return NULL;
}
}
};
bool CFather::nFlag = true;
int main()
{
CFather *p = CFather::CreatObject();
return 0;
}

Create a thread:
#include <Windows.h>
#include
using namespace std;
DWORD WINAPI fun(void* g)
{ while(1) // The thread calls the fun function and keeps printing internally { Sleep(1000); cout << ( char*)g << endl; } return 0; } int main() { char* a = “abcd”; ::CreateThread(0, 0, fun, a, 0, 0); // create thread, thread call fun function Sleep(300); while(1) // main function keeps printing { Sleep(1000); cout << “print main” << endl; } return 0; }


















Guess you like

Origin blog.csdn.net/weixin_41645749/article/details/123516582