Comprehensive Overview of C/C++ Language Features, Standard Library, and Object‑Oriented Concepts
This article provides an extensive guide to C/C++ fundamentals, covering static and const qualifiers, references versus pointers, memory‑management techniques, STL container implementations, iterator behavior, object‑oriented principles, virtual functions, smart pointers, and modern C++11 features for both beginner and experienced developers.
The introduction emphasizes that mastering C/C++ language, its standard library, and object‑oriented programming is essential for low‑level system development and high‑performance applications, while stressing careful memory management and coding standards.
1. C/C++ Language
Explains the wide applicability of C/C++ in system software, embedded systems, game development, and GUI applications, highlighting execution efficiency, direct hardware access, and popular libraries such as STL, OpenGL, and Qt.
1.1 static and const
Static variables persist for the program lifetime, can be class members shared across instances, or file‑scope globals limited to a translation unit.
Const creates immutable variables, read‑only function parameters, and const member functions that do not modify the object.
1.2 References vs. Pointers
References are aliases that must be initialized once and cannot be reseated; they improve readability.
Pointers store memory addresses, can be null, reassigned, dereferenced, and support arithmetic for arrays and dynamic allocation.
Key differences include initialization requirements, nullability, mutability, and memory footprint.
1.3 Avoiding Wild Pointers
Initialize pointers to nullptr or a valid address.
Ensure proper initialization before assignment or deletion.
Reset or delete pointers when no longer needed.
Perform null checks before use.
Prefer smart pointers (std::unique_ptr, std::shared_ptr) for automatic management.
Handle array arithmetic carefully.
1.4 malloc/free vs. new/delete
malloc/free are C functions dealing with raw memory and require explicit casting; they do not invoke constructors or destructors.
new/delete are C++ operators that allocate memory, call constructors/destructors, and provide type safety.
new performs bounds checking for arrays; malloc does not.
If malloc fails, it returns NULL and the caller must handle the error.
1.5 extern
Declares variables or functions defined in other translation units.
Enables sharing of global symbols across multiple source files.
Helps resolve circular header dependencies.
1.6 strcpy, sprintf, memcpy differences
strcpy copies null‑terminated strings; caller must ensure destination size.
sprintf formats data into a string according to a format specifier.
memcpy copies a specified number of bytes between arbitrary memory regions.
1.7 C/C++ casting scenarios
Resolve type compatibility issues.
Preserve precision in arithmetic.
Convert between pointer types, especially for low‑level memory manipulation.
Change type aliases when needed.
1.8 Default constructor generation
Generated when no user‑defined constructors exist.
Also generated when other constructors are present but a no‑arg construction is required (e.g., for containers).
1.9 Default copy constructor generation
Generated when no user‑defined copy constructor exists; performs member‑wise shallow copy.
1.10 Deep vs. shallow copy
Shallow copy duplicates member values only.
Deep copy duplicates dynamically allocated resources, requiring custom copy constructors.
Default copy constructor performs shallow copy.
2. Standard Library
The C++ Standard Library provides containers (vector, list, deque, map, set, unordered_map, etc.), algorithms, I/O streams, and utilities.
2.1 vector implementation
Uses a contiguous dynamic array with a pointer, size, and capacity.
When capacity is exceeded, allocates a larger block, copies elements, and frees the old block.
2.2 vector memory growth
When capacity is full, std::vector typically doubles its capacity, allocates new memory, copies existing elements, and updates internal pointers.
2.3 reserve vs. resize
reserve(n) only allocates memory for at least n elements; size remains unchanged.
resize(n) changes the container size, inserting default‑initialized elements or destroying excess ones.
2.4 Why vector cannot hold references
References have no independent storage and cannot be reassigned, which conflicts with the dynamic array semantics of std::vector.
2.5 list implementation
std::list is a doubly linked list where each node stores the element and pointers to previous and next nodes, enabling O(1) insertion and deletion at any position.
2.6 deque implementation
std::deque consists of multiple fixed‑size buffers linked together, allowing efficient insertion/removal at both ends while providing random access via an index‑to‑buffer mapping.
2.7 Choosing between vector, list, and deque
vector: fast random access, efficient push_back, but costly middle insertions.
list: cheap arbitrary insert/delete, no random access.
deque: fast insert/delete at both ends with reasonable random access.
2.8 priority_queue
Implemented as a heap (usually a max‑heap) stored in a container like std::vector; supports O(log N) insertion and top‑element retrieval.
2.9 map, set, multimap, multiset
All are based on a self‑balancing red‑black tree, providing ordered storage and O(log N) operations. map/set store unique keys; multimap/multiset allow duplicate keys.
2.10 unordered_map, unordered_set
Implemented with hash tables; average O(1) insertion, lookup, and deletion. Collisions are resolved via chaining or open addressing.
2.11 Iterator implementation and categories
Iterators are typically thin wrappers around pointers.
Categories: Input, Output, Forward, Bidirectional, Random‑Access.
2.12 Iterator invalidation in contiguous containers
Reallocation invalidates all iterators.
Erasing elements invalidates iterators at and after the erased position.
Resize or reserve may also invalidate iterators.
2.13 Iterator invalidation in non‑contiguous containers
list, set, map keep iterators valid except for the erased element.
Use returned iterators from insert/erase to stay valid.
2.14 STL thread safety
Standard containers are not thread‑safe for concurrent reads/writes; synchronization (mutex, shared_mutex) or concurrent containers must be used.
3. Object‑Oriented Programming
Encapsulation hides implementation details, inheritance enables code reuse, and polymorphism allows objects to be treated uniformly.
3.2 Polymorphism implementation
Uses inheritance and virtual functions; the compiler creates a vtable per class and each object contains a hidden vptr pointing to its class’s vtable.
3.3 Solving diamond inheritance
Virtual inheritance ensures a single shared base subobject.
class Base {
public:
virtual void foo() {}
};
class Derived1 : public virtual Base {};
class Derived2 : public virtual Base {};
class MostDerived : public Derived1, public Derived2 {};3.4 Function overload vs. override
Overload defines multiple functions with the same name but different signatures; override redefines a virtual function in a derived class.
class MyClass {
public:
void foo(int x) {}
void foo(double x) {}
void foo(int x, double y) {}
}; class Base {public: virtual void foo() {}}
class Derived : public Base {public: void foo() override {}}3.5 Runtime polymorphism
Dynamic binding selects the appropriate virtual function at runtime via the object's vptr and vtable.
3.6 Virtual function call process
Object contains vptr.
vptr points to class’s vtable.
Call resolves to function address from vtable.
3.7 Constructor and destructor order
Construction: base constructors first, then derived constructors down the hierarchy.
Destruction: derived destructors first, then base destructors upward.
3.8 vtable and vptr creation timing
vtable is generated at compile time; vptr is initialized during object construction to point to the appropriate vtable.
3.9 Virtual destructors
Ensures the correct derived destructor runs when deleting through a base‑class pointer, preventing resource leaks.
3.10 Smart pointers
unique_ptr – exclusive ownership, movable only.
shared_ptr – reference‑counted shared ownership.
weak_ptr – non‑owning reference to break cycles.
3.11 C++11 features used
auto type deduction, uniform initialization, range‑based for, move semantics, lambda expressions, smart pointers, rvalue references, perfect forwarding, std::thread / std::mutex , and various library enhancements.
3.12 Static vs. dynamic libraries
Static libraries are linked at compile time, increasing executable size.
Dynamic libraries are loaded at runtime, allowing sharing and easier updates.
3.13 Lvalue vs. rvalue references
Lvalue references bind to named objects and can be reassigned.
Rvalue references bind to temporaries, enabling move semantics and perfect forwarding.
The article concludes with a collection of past interview questions and links for further study.
Deepin Linux
Research areas: Windows & Linux platforms, C/C++ backend development, embedded systems and Linux kernel, etc.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.