C++ primer personal summary

1. Rvalue references

1. An lvalue is a persistent object that persists after the expression ends, and an rvalue is a temporary object that ceases to exist after the expression ends.

2. Distinguish methods: to see whether the expression can take the address, if yes, then lvalue, otherwise rvalue.

3. Top-level const means that the pointer (or reference, etc.) is itself a constant. Low-level const means that the object to which the pointer refers is a constant.

1. An lvalue reference, using T&, can only be bound to an lvalue.

2. Rvalue references, using T&&, can only be bound to rvalues.

3. Constant lvalues, const T&, can be bound to both lvalues and rvalues.

4. A named rvalue reference is considered an lvalue by the compiler.

2. Use of the const qualifier

1. Top-level const means that the pointer (or reference, etc.) is itself a constant.

2. Low-level const (low-level const) indicates that the object to which the pointer refers is a constant.

Constexpr and constant expressions

1. Constexpr specifically refers to compile-time constants, and const refers to compile-time constants and runtime constants.

4. Auto and declType type indicators

1. Auto allows the compiler to analyze the type of an expression for us. When auto defines multiple variables, they must be of the same type.

Decltype Selects and returns the data type of the operand.

5. The difference between ++ I and I ++

1.++ I returns an lvalue, and I ++ returns an rvalue (temporary variable).

2.++ I has a higher rate than I ++. Because I ++ requires a temporary variable to store the unadded I.

Inline functions and constexpr

1. The inline function is directly expanded at the call point at compile time, without the extra overhead of calling the function (save the stack, address and other information).

2. Constexpr is a function that defines constant expressions.

3. When defining a constexpr function, note that the return type of a function and the types of its arguments must be literal, and that the function body must have one and only one return statement.

4. The compiler replaces the call to a constexpr function with its resulting value.

5. Constexpr functions are implicitly specified as inline functions.

7. Cast

1. Static_cast: Any explicitly defined type conversion (other than underlying const).

2. Const_cast: Only the underlying const of an operand can be changed.

3. Reinterpret_cast: Provides a low-level reinterpretation of the bit pattern of an operand.

Dynamic_cast: runtime type identification. Dynamic type conversion. Can only be used for classes that contain virtual functions, for up and down conversions between class hierarchies. Only Pointers or references can be rotated. When cast down, return NULL for pointer if it is illegal, throw exception for reference

Signal processing

1. A signal is an interruption transmitted from the operating system to a process that prematurely terminates a program.

1.SIGABRT: Abnormal termination of a program, such as calling abort.

2.SIGFPE: Incorrect arithmetic operations, such as dividing by zero or causing an overflow.

3.SIGILL: Detect illegal instructions.

4.SIGINT: interactive attention signal is received.

5.SIGSEGV: accesses the memory illegally.

6.SIGTERM: Termination request sent to the program.

2. The C++ signal library provides the signal function to catch unexpected events.

void (*signal (int sig, void (*func)(int)))(int); //sig: signal number,func pointer to signal processing functionCopy the code

3. You can use the raise() function to generate signals.

int raise (signal sig); // SIG is the number of signals to be sent. These signals include SIGINT, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGTERM, SIGHUPCopy the code

9. Multithreaded programming

1. Create a thread

#include <pthread.h> pthread_create (thread, attr, start_routine, arg) Start_routine: the starting address of a function run by the thread, and arg: the parameter to run the function, which must be passed by casting the reference as a pointer to void. If no argument is passed, NULL is used. // The function returns 0 on success and a non-0 number on failureCopy the code

2. Terminate the thread

    pthread_exit (status)   //
Copy the code

3. Connect the thread

Pthread_join (threaDID, status) // The pthread_join() subroutine blocks the call program until the specified threaDID thread terminates. // Only threads defined as connectable at creation time can be connected.Copy the code

4. Separate threads

    pthread_detach(threadid) 
Copy the code

C++ 11 multithreaded programming

1. Create additional threads by creating objects of the STD :: Thread class. Each STD :: Thread object can be associated with a thread.

#include <thread> STD ::thread thObj(<CALLBACK>) //CALLBACK: CALLBACKCopy the code
  • Multithreaded synchronization
    • Mutex
      • It is possible that the mutex variable unlock() could not be unlocked due to a program running an exception.
    • Lock_guard
      • Passing in a mutex variable as a variable, lock() is called in the constructor and unlock() is called in the destructor.
    • unique_lock
      • The basic use of unique_lock is the same as lock_guard. The lock is performed in constructors and destructors. The difference is that it provides many constructors.
    • Condition variable
    • Semaphore
    • Advanced synchronization primitives
      • async
        • Start something early and let it run in the background, fast or slow, just when the results are needed.
      • package_task
        • Package_task essentially wraps a function as a future.
      • promise

11. C + + lock

1. Mutex: A mutex is a semaphore used to control mutually exclusive access by multiple threads to a shared resource between them.

1. Operate MUtex directly, that is, call mutex lock/ UNLOCK. If the mutex is locked by a second lock request, the second lock thread is blocked until the first lock is unlocked.

mutex.lock(); // Critical section code mutex.unlock();Copy the code

2. Lock_guard: simple lock, which is required to be locked when constructed and unlocked when released, with low performance cost. Multiple thread exclusive operation applicable to the region.

3. Unique_lock: more functions and more flexible lock, can be unlocked or re-locked at any time (reduce the granularity of the lock), the performance cost is a little higher than the former. Multithreaded mutex for flexible regions.

4. Use a separate MUtex for output streams. Because IO streams are not thread-safe.

2. Conditional locks: Conditional locks are so-called conditional variables that can be used by a thread to block the program because a condition is met. Once the condition is met, wake up a thread that is blocked because of the condition in a semaphore manner.

The implementation of wait() then checks the condition and returns if it is satisfied. If the conditions are not met, wait() unlocks the mutex and places the thread in a blocked or wait state.

Notify_one ()/notify_all() : Activates one or all waiting threads. The activated threads regain the lock.

3. The spin lock

1. A mutex is a sleep-waiting lock. Threads that do not acquire a mutex are blocked, and the processor processes other tasks rather than waiting.

2. A spin lock is a busy-waiting lock. A thread that does not acquire a spin lock will continue to request a spin lock until it obtains one.

4. Read/write locks

1. Solve the reader-writer problem.

5. The recursive locking

12.RAII

1. The full name of RAII is “Resource Acquisition is Initialization”. The constructor allocates resources and the destructor releases resources.

Stack overflow causes and solutions

1. Cause of stack overflow

1. The function call level is too deep, and the parameters, local variables and other information of the function are pushed once each call.

2. The volume of local variables is too large.

2. Solutions

1. Increase the stack memory; If the stack size does not exceed but the allocation value is small, increase the allocation size.

2. Use heap memory.


2. C + + standard library

Iostream, fstream, and sstream headers

1. The iostream: cin, cout, cerr, clog.

2. Refresh the output buffer:

1. The program ends normally.

2. The buffer is full.

3. Flush the buffer explicitly using endl(insert a newline character), Flush, and ends(insert a space character).

4. When an output stream is associated with another stream.

5. Use unitbuf to set the internal state of the stream to clear the buffer.

6. If the program terminates abnormally, the output buffer will not be flushed.

File mode :1. Read only (in), 2. Write only (out), 3. Append (app), 5. Open the file immediately to the end of the file (ATE), 6. Binary.

2. Lambda expressions

[function object arguments] (operator overloading function arguments) mutable or exception declaration -> return value type {function body}Copy the code

1 [function object argument]: identifies the start of a Lambda expression. This part must exist and cannot be omitted.

2 (operator overloading function arguments): Identifies the arguments of the overloaded () operator, which can be omitted if there are no arguments. Parameters can be passed either by value (e.g. :(a,b)) or by reference (e.g. :(&a,&b)).

3 mutable or exception statement: This part can be omitted. When passing function object arguments by value, the mutable modifier allows you to modify the copy passed in (note that it is possible to modify the copy, not the value itself). The exception declaration is used to specify exceptions thrown by a function. For example, if an integer is thrown, throw(int) can be used.

4 -> Return value type: Identifies the type of the return value of a function. This part can be omitted when the return value is void, or where there is only one return in the function body (at which point the compiler can automatically infer the return value type).

5 {function body}: Identifies the implementation of the function. This part cannot be omitted, but the function body can be empty.

3. Dynamic memory management and intelligent pointer application

1. Smart Pointers

1. Prevent memory leaks and facilitate heap memory management.

2. Smart pointer:

1. Shared_ptr: With reference counting, each copy of share_ptr points to the same memory. When the count is 0, the system automatically deletes the heap memory to which it points. Prevent circular references.

2. Unique_ptr: Only one unique_ptr can point to an object at a time.

3. Weak_ptr: Introduced to cooperate with shareD_PTR and cannot cause the increase of reference times.

4. Dynamic arrays and Allocator classes

1. Dynamic arrays

1. Allocate a dynamic array by adding square brackets after the type name of a new object to store the size of the array. Array allocation returns a pointer to the first object.

2. The allocator class

1. Allocator allows users to allocate memory before constructing objects. Allocate memory using a.locate (n), which returns a pointer to the first memory, and construct objects using a.construct(q++, args). Objects must be constructed before memory can be used or accessed.

2. A. destroy(q) is used to release objects. Allocate (p,n) is used to release memory. N must be equal to the amount of memory allocated, and objects must be released before memory is released.


3. Designer like tools

1. Explict: a class whose constructor is modified cannot be implicitly cast, but can only be explicitly cast.

2. Default: The compiler will no longer generate the default constructor if one has already been defined. Use =default to have the compiler generate the default constructor.

Copy constructors, move constructors (rvalue references), and dynamic memory management classes

1. Constructor

1. Function: assign initial value, initialize the data member of the object, called by the compiler for us.

2.① The function name is the same as the class name. ② No return value. ③ Yes/no parameter is supported. ④ Can be overloaded.

3. Call timing: The compiler calls the constructor for us at object creation time of the class.

destructors

1. Function: Releases resources.

2. ① It is the same as the class name, but must be preceded by ~. ② No parameter and no return value. ③ Because there is no parameter, no return value, so can not overload.

3. Call timing: When the function is about to exit, the compiler calls it for us

Copy the constructor

1. A copy constructor is a special constructor that takes a single parameter (often decorated with const) that is a reference to the type of that class.

CExample{CExample(const CExample & c) // Copy constructor {........ }}Copy the code

1. Initialize the newly created object by using another object of the same type.

2. The object passes function arguments as values.

3. An object is returned from a function as a value pass.

2. The copy constructor is explicitly used when defining a new object and initializing it with an object of the same type.

3. The copy constructor is implicitly called when an object of this type is passed to or returned from a function.

4. The case where a copy constructor must be defined: the class has a data member that is a pointer, or a member that represents another resource allocated in the constructor.

Move the constructor

Class ClassName{ClassName(ClassName&& TMP) // Move constructor {....... }}Copy the code

1. The move construct does not open up new space, but steals the memory space of the temporary object and takes it as its own, saving the time of opening up memory and assigning values.

2. Call timing: Move semantics are performed when temporary objects (rvalues) are used. In addition to the temporary object created by the compiler as an rvalue, STD :: Move can also be used to get an rvalue reference to an lvalue.

5. Dynamic memory management

2. Class overloading, overwriting, redefining, and converting (avoid ambiguity of overloading)

1. Function overload

1. The parameter list must be different, and the return value of the function must be different

2. Operator overload

1. Overloaded operators are functions with special names consisting of the keyword operator and the operator symbol to be overloaded after it

    Box operator+(const Box&);
Copy the code

2. Operation overloads cannot change the syntax structure.

3. The operator overload cannot change the number of operands.

4. Operation overloads cannot change the priority.

5. Operation overloads cannot change associativity.

3. Overrides exist in classes where subclasses override functions inherited from the base class. The function being overridden must be virtual, not static.

4. Redefine also known as hiding, subclasses redefine non-virtual functions with the same name in their parent class.

3. Object-oriented programming (data abstraction, data encapsulation, inheritance and dynamic binding)

1. Data abstraction refers to providing only key information to the outside world and hiding the implementation details of its background, that is, presenting only necessary information without presenting details.

2. Data encapsulation is a concept of binding data and functions that manipulate data together in object-oriented programming, so as to avoid interference and misuse by the outside world and ensure security.

3. The inheritance

1. Single inheritance (parent class contains virtual function)

1. A subclass and its parent class each have a virtual table.

2. If the subclass does not have an overwrite parent virtual function, use the parent virtual function.

3. If a subclass overwrites the virtual function of the parent class, the virtual function of the subclass overwrites the virtual function of the parent class in the virtual table.

4. If a child declares a new virtual function, the address of the virtual function is extended to the end of the virtual function table.

2. General multiple inheritance (excluding diamond inheritance)

1. If a subclass adds virtual functions, place them in the virtual function table of the first declared parent class.

2. If a subclass overrides the virtual function of its parent class, all the virtual function tables of the parent class are changed.

3. In the memory layout, the parent classes are arranged in the order in which they are declared.

3. Virtual inheritance. Virtual inheritance solves the problem of diamond inheritance where a derived class has multiple instances of an indirect parent class.

  • Classes share the state of virtual base classes through virtual inheritance.

The compiler generates a pointer to a virtual function (VPTR) and a table of virtual functions for a subclass of virtual inheritance that defines a new virtual function. This VPTR is at the front of the object’s memory (as opposed to non-virtual inheritance, which directly extends the superclass virtual function table).

2. The VPRT and vtable of the parent class are retained separately by the vINHERITED subclass.

3. The subclasses of virtual inheritance are virtual base table Pointers (VBPTR).

4. Dynamic binding

1. Static typing: The type of an object used when it is declared, even if the type is determined at compile time.

2. Dynamic type: Usually refers to a pointer or reference to the type of the object currently referred to, which is determined at run time.

3. Static binding: The binding is static type, and the corresponding function or property depends on the static type of the object, which occurs at compile time.

4. Dynamic binding: Binding is a dynamic type. The corresponding function or property depends on the dynamic type of the object and occurs at runtime. Virtual functions are dynamically bound.

5. The difference between static and dynamic binding:

1. Static binding occurs at compile time and dynamic binding occurs at run time.

2. The dynamic type of an object can be changed, but the static type cannot.

3. To be dynamic, you must use dynamic binding.

4. In the inheritance system, only virtual functions use dynamic binding, the rest are all static binding.

4. Virtual functions

1. The main function of virtual function is to realize the polymorphism mechanism. Polymorphic: use a pointer to a parent type to point to an instance of its subclass, and then call a member function of the actual subclass from the parent type’s pointer.

2. The keyword virtual modifies virtual functions.

3. Functions of virtual functions:

1. Define a subclass object and call any base class function in the object that is not overridden by a subclass.

2. When using a base pointer to a subclass object and calling an override function in a subclass, if the function is not a virtual function, the function in the base class will be called; If the function is virtual, the function in the subclass is called.

4. Each class that contains virtual functions maintains a table of virtual functions, which places the addresses of the virtual functions. Virtual function tables belong to classes. The addresses of virtual functions are stored in the virtual table in the order they are declared.

5. Virtual functions cannot be declared static.

Static member functions can be called without an object and have no hidden this pointer, while virtual functions must be called with an object and have a hidden this pointer.

2. Static functions are statically resolved (bound at compile time), while virtual functions are dynamically resolved (bound at runtime).

6. A pure virtual function is one that has no function body and is defined with “= 0” after the function name. Classes that contain pure virtual functions are called abstract classes and are not allowed to instantiate abstract classes.

    virtual int test()=0;
Copy the code

5. Templates, class templates and function templates

1. A template is a blueprint or formula for creating generic classes or functions.

1. Function template

Template <class type> ret-type func-name(parameter list) {// Function body}Copy the code

2. Class template

Template <typename type> class class-name {. // Body of the class..}Copy the code

2. In the template definition syntax, class and typename are equivalent.

3. Typename is also used to use nested dependency types. At this point, typename tells the compiler that the following string is a typename, not a member function or variable. Otherwise, the compiler does not know whether the following string is a type or a member name, causing a compilation error.

    template<class T>
    void MyMethod( T myarr ) 
    { 
        typedef typename T::LengthType LengthType; 
        LengthType length = myarr.GetLength; 
    }
Copy the code

4. Templates can only be declared or defined in global, namespace, or class scope. That is, you can’t do it in a local scope, in a function, for example, you can’t declare or define a template in main.

6. Understanding and forwarding of move

1. Move is to transfer the state or ownership of an object from one object to another.

2. Perfect forwarding: it refers to passing parameters in a function template to another function called in the function template according to the type of parameters in the template.

1. STD ::forward: performs a perfect conversion and forwards the argument as it should be, whether it is an undetermined reference type such as T&& or an explicit lvalue reference or rvalue reference.

2. Emplace_back: Internal call forward to achieve perfect forwarding.

7. A friend

Friends of a class are defined outside the class but have access to all private and protected members of the class.

2. The metaclass

Friend class Class name;Copy the code

1. All functions in this friend class have access to all private and protected members of the class.

Friend functions

Friend Return value type function name (argument list);Copy the code

4. Friends cannot be inherited.

5. Friends are one-way, not exchangeable.

Friends are not transitive.


4. Advanced topics

1. Tuple and bitset

1. The tuple type

1. Create a tuple

tuple<t1,t2,t3,t4... tn> tp=make_tuple(v1,v2,v3,v4... .vn) / / or tuple < t1, t2, t3, t4... tn> tp(v1,v2,v3,v4... vn)Copy the code

2. Analytical tuple

Get (t) // Return tie(v1,v2,v3,v4... Vn)=tp // Get the value in tuple and automatically copy it to v1,v2...Copy the code

3. Connect the tuple

    tuple_cat(tp1,tp2,....)
Copy the code

2. The bitset type

1. When constructing a string, the string can contain only ‘0’ or ‘1’; otherwise, an exception will be thrown.

2. If the binary representation of the parameter is smaller than the size of the bitset, 0 will be added in front of it. If the value is larger than bitsize, take the last part if the parameter is an integer and the first part if the parameter is a string.

2. Regular expressions

symbol meaning
. (point) Matches any character
[](brackets) Represents an interval
* (asterisk) Configure one or more arbitrary characters
+ (plus) The value contains zero or more arbitrary characters
? (question mark) The value contains zero or one arbitrary character
{}(curly braces) Represents a counting interval
\ Represents or. Only one of many can be distinguished
^ (exclusive or) Indicates the beginning of a line, or negation in a string
$(dollar sign) Represents the end of a line
(slash) According to escape
\d The decimal number is 0-9
\D A non-decimal character
\w Represents a letter or number
\W Represents a non-letter and non-number

1. Regular expression declaration

string str("\\d{4}"); regex pattern(str,regex::icase); Match_results <string::const_iterator> result; Smatch result; // Result the second way to saveCopy the code

1. Match: regex_match(str1,result,str2), returns true if str1(source string) matches str2(regular expression), false otherwise. Result [0] is the source string str1, result[1] is the first matched text, and result[2] is the second matched text…….

2. Find: regex_search(iter,iter_end,result,pattern1), look for text matching pattern1 between iterators iter and iter_end and save the result in result. Result [0] is the result of the search, result[0]. Second updates the starting position of the search.

4. Replace: regex_replace(STR,pattern,t), searches for text matching pattern at STR and replaces it with data in T.

Random number 3.

1. Random seed: A random seed (unsigned type) is a number used to generate random numbers.

2. Random () cannot be used in C++. Because random is not an ANSI C standard, it cannot be compiled under GCC, VC, etc.

3. The C++ standard library provides a random number generator rand, which returns a pseudo-random integer evenly distributed between 0 and RAND_MAX, RAND_MAX must be at least 32767.

4. Srand () can specify different numbers (unsigned integer variables) as seeds. But if the seeds are the same, the pseudo-random sequence is the same.

4. Exception handling

1.C++ throws and tries… The catch statement implements the handling of exceptions.

1. Throw an exception

Throw expression;Copy the code

2. Catch exceptions

Try {statement group} catch(exception type) {exception handler code}... Catch (exception type) {exception handling code}Copy the code

2. Exception throwing

1. If the exception is not handled in this function, it is thrown to the function at the next level.

3. Standard exception classes, derived from the Exception class.

Bad_typeid: Throws this exception if its operand is a pointer to a polymorphic class whose value is NULL.

Bad_cast: When casting a reference from a polymorphic base class object (or reference) to a derived class using Dynamic_cast, this exception is thrown if the casting is unsafe.

Bad_alloc: This exception is thrown when there is not enough memory for dynamic memory allocation with the new operator.

Out_of_range: This exception is raised when the at member functions of a vector or string access elements based on subscripts that are out of bounds. Access with [] does not throw an out_of_range error.

      5.ios_base::failure

5. Namespace Namespace

1. Namespace: it is actually a memory region named by the programmer. The programmer can specify some named space domains as needed, and put some global entities in each namespace, thus separating them from other global entities.

Namespace namespace_name {// code declaration}Copy the code

2. Using: The using namespace namespace_name directive tells the compiler that subsequent code will use the name of the specified namespace, so it does not need to be preceded by the name of the namespace.

6. Multiple inheritance and virtual inheritance

Inherit from the object programming section.

7. The working principle of new and DELETE, the application of overloaded new and DELETE and malloc and free, locating new expressions

1. Working principle of New

1. Simple data types (including basic data types and types that do not require constructors). Simple data types directly call operator new to allocate memory; New_handler can handle new failure cases; Instead of returning NULL on failed allocation, as malloc does, new throws an exception. The mechanism of exception catching should be used to determine whether the allocation was successful.

2. For complex data types (objects that need to be initialized by constructors), call operator new to allocate memory and then call the constructor on the allocated memory.

2. Working principle of New []

1. For simple data types (including basic data types and types that do not require a destructor), new[] calculates the size and calls operator new.

2. For complex data types (objects need to be destroyed by the destructor), new[] stores additional array sizes.

3. Working principle of DELETE

1. Simple data types (both basic and non-destructor types), delete simple data types simply call the free function by default.

2. For complex data types (objects need to be destroyed by the destructor), delete for complex data types the destructor is called first and then operator delete is called.

4. Working principle of DELETE []

1. For simple data types (including basic data types and types that do not require destructors), delete is called on each element of the array based on the additional size information held by new [].

2. For complex data types (objects need to be destroyed by the destructor), delete is called on each element of the array based on the additional size information held by new [].

5. Operator new and operator delete

6. Compare new and delete with malloc and free

1. Different returns: Malloc returns void * and new returns a pointer to the corresponding class type.

2. Malloc needs to specify the allocated size, new does not need to specify the size.

3. Malloc allocates memory and does not initialize it. New allocates memory at the same time.

4. Malloc is a function and new is an operator.

5. The memory allocation positions are different. New is allocated to free storage and malloc is allocated to the heap.

6. When new memory allocation fails, bac_alloc is raised, which does not return NULL. Returns NULL if malloc fails to allocate memory.

7. Locate the new expression

1. Allocate memory at the specified address and place an appropriately sized instantiated object into the address.

New (place_address) type(initializer-list) // Place_address must be a pointer. Initializer-list is the initialization list of the type.Copy the code

8. Overloaded new and delete

Objectives: 1. Increase the speed of allocation and return; 2. Heap fragmentation; 3. Reduce the space overhead associated with the default memory manager……

2. Operator new() returns a void* and allocates memory. It’s an action that the compiler ensures is out of our control.

3. Operator delete() takes a void* to the memory allocated by operator new(), and a void* is a pointer to the destructor that removes the object from the storage unit. Operator delete() returns void.

4. Overload new and delete

1. When we overload operator new() and operator delete(), we simply change the way we allocate memory.

8. Data member Pointers and function Pointers in classes

Function Pointers

int (*pf)(int,int); //pf is a function pointer to a function with two parametersCopy the code

2. Pointers to data members of a class

Int class_name:: * pf // pointer to the int data member of class_nameCopy the code

3. Pointers to member functions in a class

Int class_name:: *(pf)(int,int) // A pointer to a function with two parameters in class_nameCopy the code

9. Bitfields (passing binary data) and volatile qualifiers (additional modifications to types)

1. A domain

Struct bs {// int a:8; // int a:8; // int b :8; // int b :8; int b:2; int c:6; int :2; };Copy the code

1. Function: Saves memory resources and makes data structure more compact.

2. A bit field must be stored in the same byte and cannot span two bytes. Therefore, the length of a bit field cannot be larger than one byte.

3. The address fetch operator & cannot be applied to the bit-domain field.

4. Bit-field fields cannot be static members of a class.

5. The positions of bit-field fields in memory are placed from the lowest to the highest.

6. When specifying a member as a bitfield, it must be of type int,unsigned int, or signed int

7. The bit-field can have no bit-domain name, which is only used to fill or adjust position. Nameless bit fields are not available.

8. Alignment of bit fields

1. If adjacent bit-field fields have the same type and the sum of their bitwidths is smaller than the sizeof the type, the following fields are stored adjacent to the previous one until they cannot contain each other.

2. If the sum of the bitwidths of adjacent bitfields of the same type is greater than sizeof the type, the following fields start from the new storage unit and their offset is an integer multiple of the sizeof their type.

3. If the type of two adjacent bitfields is different, then the specific implementation of each compiler is different. VC6 adopts the uncompressed mode,GCC and dev-C ++ both use the compressed mode.

4. The total size of the entire structure is an integer multiple of the size of the widest primitive member.

5. If bit-field fields are interspersed with non-bit-field fields, no compression is performed. (Not for all compilers).

2. The volatile qualifier

1. Variability: The register contents of the volatile variable corresponding to the previous statement are not directly used by the next statement, but are re-read from memory

2. Non-optimizability: Volatile tells the compiler not to perform any radical optimizations on this variable, or even eliminate the variable directly, to ensure that the instructions written by the programmer in the code will be executed.

3. Sequentiality: Sequentiality between Volatile variables is guaranteed and the compiler does not perform out-of-order optimizations.

10. Extern “C” (use links to put C++ code together with code from other languages)

   1.extern

Extern can be placed in front of a variable or function to indicate that the definition of the variable or function is in another file, prompting the compiler to look for its definition in another module if it encounters the variable or function.

2. Link specifies: when it is used with “C”, as in:

extern "C" void fun(int a, int b); // Tell the compiler to translate fun into C instead of C++ when compiling the function name.Copy the code

3. Extern refers to another file in a smaller scope than include, which can refer to the entire contents of another file.


C++ design pattern

  • The factory pattern

    • The creation of objects does not expose the creation logic to the client and is done by using a common interface to point to the newly created object.
    • 1. Simple factory mode
      • The main feature is that you need to make judgments in the factory class to create corresponding products, and when adding new products, you need to modify the factory class. Using the simple factory pattern, we only need to know the specific product model to create a product.
      • disadvantages
        • The factory class centralizes the creation logic of all product classes. If the number of products is large, the factory class will become very bloated.
    • 2. Factory method pattern
      • Define an interface that creates an object, and subclasses instantiate the interface to do the actual creation. If you need to add a new product class, you can simply extend a corresponding factory class.
      • disadvantages
        • With a lot of product class data, a lot of factory classes need to be implemented, which undoubtedly increases the amount of code.
    • 3. Abstract factory pattern
      • The abstract factory pattern provides an interface to create a series of related or interdependent objects without specifying their concrete classes.
      • disadvantages
        • When adding a new family of products, not only the actual product class, but also the need to add a new creation interface, the extension is relatively difficult.
  • The strategy pattern

    • Strategy pattern is refers to the definition of a series of algorithms, encapsulate them separately, and to get them to replace each other, the algorithm can be used independently of its clients, also said the functions performed by these algorithms type is the same, external interface is the same, just different strategies for the characters show different environmental role behavior.
    • advantages
      • Instead of using a lot of if… Else, using the policy pattern reduces complexity and makes the code more maintainable.
    • disadvantages
      • A large number of policy classes may need to be defined and provided to the client.
    • 1. The traditional strategy model
    • 2. Use function Pointers to implement policy patterns
  • Adapter mode

    • The adapter pattern transforms the interface of one class into another interface that the client wants, making it possible for classes to work together that would otherwise not work together due to interface incompatibations.
    • disadvantages
      • Too much use of adapters can make the system very cluttered and difficult to grasp as a whole.
    • 1. Implement the adapter pattern using composition
    • 2. Implement the adapter pattern using inheritance
  • The singleton pattern

    • Ensures that a class can have only one instantiated object and provides a global interface that can access it.
      • A singleton class can consist of only one instantiated object
      • The singleton class must provide an instantiation object of its own.
      • A singleton class must provide an interface to access a uniquely instantiated object.
    • 1. Lazy singleton pattern
      • An object is instantiated the first time it is used.
    • 2. Hungry singleton mode
      • Instantiation occurs when the singleton class is defined.
  • The prototype pattern

    • Specify what kind of objects to create with prototype instances, and create new objects by copying these prototypes.
  • Template pattern

    • Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. The template approach allows subclasses to redefine specific steps of an algorithm without changing the structure of that algorithm.
    • disadvantages
      • Each different implementation requires a subclass to implement, resulting in an increase in the number of classes, making the system larger.
  • Builder model

    • The construction of complex objects is separated from their representation, allowing the same construction process to produce different representations.
    • advantages
      • By separating object creation from presentation, the client does not need to know the specifics of the build.
      • When adding a new product object, you only need to add its concrete build class, without modifying the original code, which is easy to expand.
  • The appearance model

    • Define a consistent interface for a set of interfaces in the subsystem;
    • The facade pattern provides a high-level interface that makes the subsystem easier to use;
    • For complex systems, the system provides a simple interface for the client to encapsulate the responsible implementation process, and the client does not need to connect to the details of the system.
    • advantages
      • The loose coupling between subsystem and client is realized.
      • The client shields subsystem components, reducing the object data that the client needs to process, making the subsystem easier to use.
      • Better division of the design level, for the later maintenance is more easy.
  • Portfolio model

    • By combining objects into a tree structure to represent a partial-whole hierarchy, the composite pattern makes client use of single objects and composite objects unitary.
  • The proxy pattern

    • Provide a proxy for other objects to control access to this object.
    • advantages
      • Clear responsibilities. The real role is only responsible for implementing the actual business logic, and does not care about other things that are not part of this responsibility, and performs specific tasks through late agents. The code will be clean and clean.
      • A proxy object can act as an intermediary between the client and the target object, thus protecting the target object.
      • Good scalability.
  • The flyweight pattern

    • Use sharing techniques to effectively support a large number of fine-grained objects.
      • When there are a large number of objects, the common part of them is abstracted out. If there is the same business request, directly return the existing objects in memory, avoiding re-creation.
    • The share pattern divides the information of an object into two parts:
      • Internal state
        • Internal state is the information that is shared, stored inside the share object and does not change with the environment.
      • External state
        • External state is not shareable; it changes with the environment and is controlled by the client.
  • The bridge model

    • Separate the abstract part from the implementation part so that they can be transformed independently.
    • advantages
      • The implementation is separated from the implementation, and then the abstraction is realized, so that the concrete implementation of the object depends on the abstraction, which satisfies the dependency inversion principle.
      • Better scalability.
      • Dynamic switching implementation. The bridge pattern achieves the separation of abstraction and implementation, and in the implementation of the bridge pattern, the concrete implementation can be dynamically selected.
  • Decorative pattern

    • Add some extra functionality to an object dynamically.
      • Wrap the real object by creating a wrapper object, a decoration.
    • Decorator mode is more flexible than production subclasses in terms of new additions.
  • Memo mode

    • Capture the internal state of an object and store the state outside of the object without breaking encapsulation.
    • Role classes to be defined in the memo pattern:
      • Originator
        • Responsible for creating a Memento that records its own internal state at the current moment and can be used to restore the internal state.
      • Memento
        • Stores the internal state of Originator objects and prevents objects other than Originator from accessing memos.
        • Memos have two interfaces
          • Narrow interface
            • The Caretaker sees only a narrow interface to the memo and can only pass the memo to other objects.
          • Wide interface
            • The Originator sees the memo’s wide interface, allowing it to access all the data needed to return to the previous state.
      • Caretaker = Caretaker
        • Is responsible for Memento and cannot access or operate the contents of Memento.
  • The mediator pattern

    • A mediation object encapsulates a set of object interactions.
      • The mediator makes objects loosely coupled without explicitly referring to each other, and can independently change their previous interactions.
  • Chain of Responsibility model

    • Giving multiple objects the opportunity to process the request avoids the coupling between the sender and receiver of the request by connecting the objects into a chain and passing the request along the chain until one object processes it.
  • Observer model

    • Defines a one-to-many dependency between objects in which all dependent objects are notified and updated automatically when an object’s state changes.
    • The observer and the observed
      • The observed object itself should contain a container that holds the observer object and notifies all observers in the container to update automatically when the observed object itself changes.
      • The observer object can be registered in the observed, after the completion of registration can detect the changes of the observed, receive the notice of the observed. Of course, the observer can also be logged out, stopping the monitoring of the observed.