1. moveMeaning: The essence of move is to convert a left value into a right value reference, thereby triggering move semantics (the move operation is implemented by the type’s move constructor/assignment operator, and resource ownership is transferred).Usage: Clearly identify scenarios where ownership needs to be transferred; efficient insertion in container operations (using move when inserting large objects into containers to avoid copying); returning local objects can explicitly indicate move; avoid expensive copy operations (moving resource types like dynamic memory, file handles, etc. is more efficient than copying).Summary: Essentially a type conversion that marks a left value as a right value, allowing the invocation of move semantics; does not actually move data, the move operation is implemented by the type’s move constructor; applicable to resource management types, such as string, vector, smart pointers, etc.; avoid misuse, as it is meaningless for different types or types that do not implement move semantics.2. Left Value References and Right Value ReferencesLeft value references are mainly used for function parameter passing and returning references.Right value references enable move semantics move and perfect forwarding forward.3. Memory Layout of Virtual FunctionsVirtual functions are a key mechanism for implementing runtime polymorphism, and their underlying implementation relies on the virtual function table and virtual pointer. (Member functions declared with virtual allow subclasses to override; when calling a virtual function through a base class pointer or reference, the function corresponding to the object’s dynamic type is actually executed.)Memory Layout: Virtual Function Table and Virtual PointerThe virtual function table, or vtable, is an array of function pointers that stores the addresses of all virtual functions of the class; the subclass’s vtable inherits the virtual functions of the parent class and overrides the functions that are redefined.Each object internally contains a hidden pointer vptr that points to the vtable of the class it belongs to.When a virtual function is called, the compiler uses vptr to find the object’s vtable, retrieves the corresponding function pointer from the vtable, and then executes that function.Virtual functions involve multiple inheritance, where each base class has its own virtual function pointer and virtual function table; the subclass’s vtable merges all base class virtual functions.A virtual destructor must be declared; otherwise, deleting a base class pointer may lead to memory leaks (if the base class’s destructor is not virtual, the subclass’s destructor will not be called when the subclass object is released through a base class pointer, leading to memory leaks); a virtual destructor will be added to the virtual function table to ensure the correct calling of the subclass’s destructor.4. Memory LeaksHeap memory leaksObjects allocated with new or memory allocated with malloc are not released.Array leaks occur when delete is used without brackets during release.Memory leaks caused by circular references in smart pointers, where shared_ptr references each other, preventing the count from reaching zero and resources from being released.Resource leaks (files, networks, threads)System resources are not released.5. Principle of shared_ptrEach shared_ptr instance points to the same object while sharing a counter; when a new shared pointer is created or an existing shared pointer is copied, the counter increases; conversely, when destroyed or reset, the counter decreases; when the counter reaches zero, the object is automatically deleted.6. Virtual InheritanceVirtual inheritance is a mechanism used to solve the diamond inheritance problem, ensuring that in a multiple inheritance hierarchy, the members of the common base class have only one copy in the final derived class.Diamond inheritance occurs when a derived class inherits from the same base class through multiple paths, leading to multiple copies of the base class’s members in the derived class, causing data redundancy and ambiguity. By declaring virtual inheritance, only one copy of the data exists in the final derived class, and virtual inheritance is implemented through virtual base class pointers and virtual base class tables to avoid duplication of the base class.7. Size of a ClassThe size of a class is determined by several factors:The size of non-static members.Memory alignment and padding.The impact of virtual functions, where the virtual function table pointer is 8 bytes.The impact of virtual inheritance, where the virtual base class pointer is also 8 bytes.An empty class has a size of 1 byte, ensuring that each object has a unique memory address, with 1 byte guaranteeing address uniqueness.8. Deep Copy and Shallow CopyShallow copy copies the member variables of the object; if the copied variable is a pointer, only the pointer address is copied, not the content it points to.Deep copy not only copies the member variables of the object but also allocates new memory space and copies the content pointed to by the pointer.9. Default Member Functions of a ClassConstructor initializes the object.Copy constructor initializes a new object with another object of the same type.Copy assignment operator assigns the value of one object to another object of the same type.Move constructor initializes an object using a right value (temporary object).Move assignment operator assigns a right value (temporary object) to an existing object.Destructor cleans up the object’s resources.10. Type Conversionstatic_cast is a static conversion mainly used for known safe type conversions, which will perform type checking at compile time, such as converting basic data types, converting subclass pointers to base class pointers, but not base class pointers to subclass pointers.dynamic_cast is a dynamic conversion mainly used for conversions between base and subclass, especially safe downcasting (downcasting requires polymorphism, i.e., virtual functions); if the base class does not have virtual functions, it cannot be used for downcasting.const_cast removes const/volatile (telling the compiler “the variable may be modified externally, do not optimize access”); if the object itself is not const, const_cast can be used to remove the const attribute from the pointer.
const char* str = "Hello";
char* p = const_cast<char*>(str);
11. Vector Expansion Mechanism and How to Optimize Expansion PerformanceVector uses exponential growth, expanding the capacity by approximately 1.5 to 2 times each time.It allocates new memory, copies data, and releases old memory.Optimization: If you need to store a large amount of data continuously, use reserve to preallocate space to avoid multiple expansions.12. const and constexprconst is used to define constants, and its value cannot be modified after declaration in the program; its value cannot be guaranteed to be constant at compile time.constexpr constants must have their values determined at compile time and can only be used in constant expressions or variables; it significantly reduces assembly instructions and improves performance in frequently accessed constants.13. Function RedefinitionIf a function is directly defined in a header file and included in multiple cpp files, it will lead to redefinition errors.Use static to resolve this; static can limit the function to the current translation unit.Use inline to resolve this; having the same function definition in multiple translation units is allowed, and only one function definition is retained during linking.The standard solution is inline + namespace, commonly used in the standard library.<span><span>namespace test {</span></span>inline type function_name {};}Summary: static is “hiding”, inline is “unifying merging”, and namespace is “categorical management”.14. Definition and DeclarationDeclaration is used to inform the compiler of the name and type of a variable or function but does not allocate memory for it.Definition, based on the declaration, is also responsible for allocating memory space for the variable or function, such as initialization operations.A variable or function can be declared multiple times but can only be defined once.15. Default Copy ConstructorThe default copy constructor performs a shallow copy, copying the values of the object’s member variables one by one; for pointer members, it only copies the address, which can lead to the new object and the original object’s pointer members pointing to the same memory block, causing double deletion when the destructor is invoked.To solve this problem, an explicit copy constructor should be written, which during construction will reallocate memory for pointer members and copy the original object’s data into the new memory space.16. nullptr — Replacing NULL as the null pointer constantnullptr is a true null pointer constant, of type std::nullptr_t, which will not be confused with integer types.17. Pure Virtual Functions and Abstract ClassesA pure virtual function is a virtual function that has only a declaration and no implementation.The introduction of pure virtual functions is to impose interface constraints on subclasses, ensuring that derived classes must override this function. Any class containing at least one pure virtual function is called an abstract class.18. Virtual Function Table and Virtual Function Pointer
Virtual Function Table (vtable)
-
When a class contains at least one virtual function, the compiler generates a virtual function table for that class.
-
The virtual function table is an array of pointers, where each entry stores the actual function entry address of the class’s virtual functions.
-
The order of function addresses in the table is determined by the order of declaration in the class.
Virtual Function Pointer (vptr)
-
Each object of a class containing virtual functions implicitly contains a virtual function pointer vptr in its memory layout.
-
<span><span>vptr</span></span>is automatically initialized by the compiler during object construction, pointing to the corresponding virtual function table of the current class. -
When a virtual function is called through a base class pointer or reference, the runtime uses
<span><span>vptr</span></span>to look up the vtable and determine which function to actually call.
Memory Structure of Virtual Functions:
-
When a class contains virtual functions, the compiler creates a virtual function table for that class, storing the addresses of the virtual functions;
-
In the memory layout of each class object, there will be a virtual function pointer
<span><span>vptr</span></span>at the front; -
<span><span>vptr</span></span>is automatically initialized during object construction, pointing to the virtual function table of the current class; -
Using
<span><span>vptr</span></span>+ offset, the program can dynamically call the correct function at runtime, supporting polymorphism.