10 Code Snippets to Quickly Review Core C++ Concepts (Review + Practical Use)

Sometimes when writing C++, you may find that knowledge points you have learned are easily forgotten after a while. For example, does <span>std::move</span> actually empty the object? Does the iterator become invalid when a <span>vector</span> is resized? These questions can seem abstract when looking at the documentation, but a few lines of code can immediately jog your memory.

Below are 10 common core C++ concepts. They are frequently encountered in daily development and are areas where many students may become confused while learning or working on projects. I have provided a brief example, key points, and some common pitfalls encountered in practice for each point. I hope this can serve as a “quick reference checklist” to quickly recall related issues in the future.

📚 The C++ Knowledge Base has been launched on ima! The current content covered by the knowledge base is shown in the image below:

10 Code Snippets to Quickly Review Core C++ Concepts (Review + Practical Use)

📌 Students interested in the knowledge base can add the assistant vx (chuzi345) with the note 【Knowledge Base or click 👉 C++ Knowledge Base (tap to jump) to view the complete introduction to the knowledge base~

1. RAII: Resource Acquisition Is Initialization

#include <iostream>
#include <fstream>

struct FileGuard {
    std::ofstream file;
    FileGuard(const std::string& name) : file(name) {}
    ~FileGuard() { /* Automatically close the file upon destruction */ }
};

int main() {
    FileGuard fg("log.txt");
    fg.file << "RAII demo\n";
}

Key Points The idea of RAII: The lifecycle of an object is bound to the resource. The constructor acquires the resource, and the destructor releases it, ensuring that resources are not leaked whether returning normally or throwing an exception.

Practical Experience

  • RAII is widely applied: <span>std::lock_guard</span> manages locks, and <span>std::unique_ptr</span> manages dynamic memory.
  • If you write your own resource management class, be careful about whether copy constructors and assignment operators need to be deleted (a typical practice is to disable copying and support moving).
  • A common interview question: Why is RAII more natural than try/finally? — The C++ object model allows RAII to automatically execute destructors at the end of the scope.

2. Smart Pointers: Safer Resource Management

#include <memory>
#include <iostream>

int main() {
    auto p = std::make_unique<int>(42);
    std::cout << *p << "\n";

    auto sp = std::make_shared<int>(99);
    auto sp2 = sp; // Reference count +1
    std::cout << sp.use_count() << "\n"; // Outputs 2
}

Key Points

  • <span>unique_ptr</span> has exclusive ownership, cannot be copied, only moved.
  • <span>shared_ptr</span> uses reference counting, allowing multiple objects to share it, but be cautious of circular references (use <span>weak_ptr</span> to break the cycle).

Practical Experience

  • Common interview question: Why is <span>make_unique</span> safer than <span>unique_ptr<T>(new T(...))</span>? Answer: It avoids resource leaks caused by temporary objects in the event of exceptions (strong exception safety).
  • In performance-sensitive scenarios, try to minimize the use of <span>shared_ptr</span>, as reference counting incurs additional overhead.

3. <span>vector</span> vs <span>list</span>: Differences in Memory Layout

#include <vector>
#include <list>
#include <iostream>

int main() {
    std::vector<int> v{1,2,3};
    std::list<int> l{1,2,3};

    v.push_back(4); // Amortized O(1)
    l.push_back(4); // O(1)
}

Key Points

  • <span>vector</span> has contiguous memory, supports random access, is cache-friendly, and is suitable for traversal and appending at the end.
  • <span>list</span> is a doubly linked list, with scattered nodes, suitable for inserting/deleting in the middle, but has poor traversal performance.

Practical Experience

  • Common interview question: <span>vector</span> expansion mechanism. The default strategy is to double the capacity when insufficient, which may lead to iterator invalidation.
  • <span>list</span> is used less frequently in actual projects unless there are frequent middle insertions; otherwise, in most cases, <span>vector</span> is superior.

4. <span>move</span> Semantics and Rvalue References

#include <iostream>
#include <string>

int main() {
    std::string a = "Hello";
    std::string b = std::move(a);

    std::cout << "b: " << b << "\n";
    std::cout << "a: " << a << "\n"; // a is still valid but content is undefined
}

Key Points

  • The significance of move semantics: Avoid unnecessary deep copies, significantly improving performance, especially when passing temporary objects.
  • <span>std::move</span> does not actually “move”; it merely converts an lvalue to an rvalue reference, and whether it actually moves depends on the implementation of the target type.

Practical Experience

  • Common mistake: Continuing to use the original object after std::move, which may introduce potential bugs.
  • Interview point: If a class manages its own resources, it must implement move constructors and move assignment operators; otherwise, copy semantics will be triggered.

5. <span>constexpr</span>: Compile-time Computation

constexpr int square(int x) { return x * x; }
int arr[square(5)]; // OK

Key Points

  • <span>constexpr</span> ensures that functions or variables can be evaluated at compile time.
  • It is safer and more flexible than <span>#define</span> and <span>const</span>.

Practical Experience

  • <span>constexpr</span> does not mean “only executed at compile time”; it can also be called at runtime.
  • It is very common in template metaprogramming, array sizes, lookup functions, etc.

6. <span>auto</span> and <span>decltype</span>

int x = 42;
auto y = x;          // int
decltype(x) z = 0;   // int

Key Points

  • <span>auto</span> is responsible for type deduction, simplifying code.
  • <span>decltype</span> maintains type consistency (for example, deducing function return values).

Practical Experience

  • Common pitfall: <span>auto</span> will lose <span>const</span> and reference qualifiers, while <span>decltype(auto)</span> retains them.
  • Often used together in generic programming, such as C++14’s function return type deduction.

7. Range <span>for</span>

#include <vector>
#include <iostream>

int main() {
    std::vector<int> nums{1,2,3};
    for (auto&& n : nums) {
        n *= 2;
    }
}

Key Points

  • Range for is syntactic sugar; it still uses iterators under the hood.
  • Note to write <span>auto&</span> to modify elements.

Practical Experience

  • If the container is large, <span>auto n</span> will incur a copy, so it’s better to use <span>const auto& n</span>.
  • This is better for both code readability and performance, and is recommended over manually iterating with iterators.

8. Lambda Expressions

#include <algorithm>
#include <vector>
#include <iostream>

int main() {
    std::vector<int> v{3,1,4};
    std::sort(v.begin(), v.end(), [](int a, int b) { return a < b; });
}

Key Points

  • Supports capturing external variables, with flexible syntax.
  • Commonly used with STL algorithms, it is a typical modern C++ style.

Practical Experience

  • <span>[&]</span> captures all by reference, while <span>[=]</span> captures all by value; be able to explain the difference in interviews.
  • In large projects, it is recommended to explicitly list captured variables to avoid maintenance difficulties.

9. <span>enum class</span>

enum class Color { Red, Green, Blue };
Color c = Color::Red;

Key Points

  • Avoids naming pollution and implicit conversions of traditional <span>enum</span>.
  • Type-safe and clearly scoped.

Practical Experience

  • Common interview question: Why can’t <span>enum class</span> be directly compared to <span>int</span>? Answer: C++ avoids implicit conversions to ensure strong type safety.

10. Multithreading and <span>std::thread</span>

#include <thread>
#include <iostream>

void work() {
    std::cout << "Thread work\n";
}

int main() {
    std::thread t(work);
    t.join();
}

Key Points

  • <span>join()</span> waits for the thread to finish, while <span>detach()</span> separates the thread.
  • The thread function can be a regular function, a lambda, or a member function.

Practical Experience

  • Common mistake: Accessing a destroyed object after the thread has been detached, leading to dangling references.
  • Common interview question: How to avoid race conditions? Common methods include <span>std::mutex + std::lock_guard</span>.

Summary

These 10 code snippets cover five major areas: resource management, containers, type deduction, modern syntax, and concurrency. If you are preparing for an interview, it is recommended to practice:

  1. Writing classes with resource management (RAII + move semantics).
  2. Comparing the performance differences of containers in different scenarios.
  3. Proficiently using lambdas in conjunction with algorithms.

Mastering these fundamentals will help you tackle most core C++ interview questions.

Recommended reading:

C++ Direct Access to Major Companies (For students interested in the training camp, you can read this article to learn about the training camp details, or add vx: chuzi345 to quickly learn about the training camp related information)

From Multithreading to Asynchronous: Step by Step Implementing a Usable Logging System

CMake Black Technology: Unifying Windows/Linux/Mac Development Environments with One Set of Scripts

Leave a Comment