一线大厂C++高频面试题合集

文章目录

1. C++中虚函数的实现原理是什么?

答案解析
虚函数通过虚函数表(vtable)实现动态多态。每个包含虚函数的类有一个虚表,存储虚函数指针,对象实例包含指向虚表的指针(vptr)。调用虚函数时,通过vptr查找vtable并执行对应函数。

  • 编译器在类构造时生成vtable。
  • 派生类重写虚函数时,vtable中对应条目被替换。

代码示例

class Base {
   
public:
    virtual void func() {
    std::cout << "Base\n"; }
};

class Derived : public Base {
   
public:
    void func() override {
    std::cout << "Derived\n"; }
};

int main() {
   
    Base* b = new Derived();
    b->func();  // 输出: Derived
    delete b;
    return 0;
}

2. 智能指针有哪些类型?如何避免循环引用?

答案解析
C++11引入智能指针:unique_ptr(独占)、shared_ptr(共享)、weak_ptr(弱引用)。

  • 循环引用:两个shared_ptr互相引用导致无法释放。
  • 解决:使用weak_ptr打破循环,weak_ptr不增加引用计数。

代码示例

#include <memory>
class Node {
   
public:
    std::shared_ptr<Node> next;
    std::weak_ptr<Node> prev;  // 避免循环引用
};

int main() {
   
    auto n1 = std::make_shared<Node>();
    auto n2 = std::make_shared<Node>();
    n1->next = n2;
    n2->prev = n1;  // weak_ptr不增计数
}

3. C++中RAII的核心思想是什么?

答案解析
RAII(Resource Acquisition Is Initialization)通过对象生命周期管理资源:

  • 构造时获取资源,析构时释放资源。
  • 避免手动管理资源,防止泄漏。

代码示例

#include <iostream>
class Lock {
   
    std::mutex& m;
public:
    Lock(std::mutex& mtx) : m(mtx) {
    m.lock(); }
    ~Lock() {
    m.unlock(); }
};

std::mutex mtx;
void func() {
   
    Lock lock(mtx);  // 自动加锁
    std::cout << "Locked\n";
}  // 离开作用域自动解锁

4. 什么是move语义?如何实现?

答案解析
Move语义通过转移资源所有权优化性能,避免拷贝。C++11引入右值引用(&&)支持move。

  • std::move将对象转为右值,触发移动构造函数。

代码示例

#include <utility>
class MyString {
   
    char* data;
public:
    MyString(const char* s) : data(new char[strlen(s) + 1]) {
    strcpy(data, s); }
    MyString(MyString&& other) noexcept : data(other.data) {
    other.data = nullptr; }
    ~MyString() {
    delete[] data; }
};

int main() {
   
    MyString s1("hello");
    MyString s2 = std::move(s1);  // 移动构造
}

5. C++中const和constexpr的区别?

答案解析

  • const:运行时常量,修饰不可变变量。
  • constexpr:编译时常量,计算必须在编译期完成,常用于函数或对象初始化。

代码示例

const int a = 10;  // 运行时常量
constexpr int b = 10;  // 编译时常量
constexpr int square(int x) {
    return x * x; }
int arr[square(5)];  // 编译期计算

6. 模板元编程是什么?举例说明。

答案解析
模板元编程(TMP)利用模板在编译期执行计算,常见于类型推导和常量计算。

  • 优点:零运行时开销。

代码示例

template<int N>
struct Factorial {
   
    static const int value = N * Factorial<N - 1>::value;
};
template<>
struct Factorial<0> {
   
    static const int value = 1;
};

int main() {
   
    std::cout << Factorial<5>::value << "\n";  // 输出: 120
}

7. C++中多线程同步有哪些方法?

答案解析

  • 互斥锁(std::mutex):保护共享资源。
  • 条件变量(std::condition_variable):线程间通信。
  • 原子操作(std::atomic):无锁同步。

代码示例

#include <mutex>
std::mutex mtx;
int counter = 0;

void increment() {
   
    std::lock_guard<std::mutex> lock(mtx);
    counter++;
}

8. 什么是CRTP?如何使用?

答案解析
CRTP(Curiously Recurring Template Pattern)通过模板让基类访问派生类成员,实现静态多态。

代码示例

template<typename T>
class Base {
   
public:
    void func() {
    static_cast<T*>(this)->impl(); }
};

class Derived : public Base<Derived> {
   
public:
    void impl() {
    std::cout << "Derived\n"; }
};

int main() {
   
    Derived d;
    d.func();  // 输出: Derived
}

9. C++中lambda表达式的捕获方式有哪些?

答案解析

  • [=]:按值捕获所有外部变量。
  • [&]:按引用捕获所有外部变量。
  • [x, &y]:x按值,y按引用捕获。

代码示例

int x = 10;
auto f = [x]() mutable {
    return ++x; };  // mutable允许修改捕获的值
std::cout << f() << "\n";  // 输出: 11

10. C++中如何实现线程安全的单例模式?

答案解析
使用双重检查锁(DCLP)或静态局部变量(C++11后线程安全)。

代码示例

class Singleton {
   
    static std::mutex mtx;
    static Singleton* instance;
    Singleton() {
   }
public:
    static Singleton* getInstance() {
   
        if (!instance) {
   
            std::lock_guard<std::mutex> lock(mtx);
            if (!instance) instance = new Singleton();
        }
        return instance;
    }
};
std::mutex Singleton::mtx;
Singleton* Singleton::instance = nullptr;

11. 虚继承的作用是什么?

答案解析
虚继承解决菱形继承问题,避免基类重复实例化,仅保留一份基类副本。

代码示例

class A {
   };
class B : virtual public A {
   };
class C : virtual public A {
   };
class D : public B, public C {
   };

12. C++中explicit关键字的作用?

答案解析
explicit防止构造函数隐式转换,确保显式调用。

代码示例

class MyClass {
   
public:
    explicit MyClass(int x) {
   }
};

int main() {
   
    // MyClass m = 5;  // 错误,需显式
    MyClass m(5);   // 正确
}

13. 什么是SFINAE?如何应用?

答案解析
SFINAE(Substitution Failure Is Not An Error)是模板推导失败不报错的规则,用于条件编译。

代码示例

template<typename T, typename = std::enable_if_t<std::is_integral_v<T>>>
void func(T) {
    std::cout << "Integral\n"; }

int main() {
   
    func(5);    // 输出: Integral
    // func(5.5);  // 编译失败
}

14. C++中如何实现类型安全的枚举?

答案解析
使用enum class替代传统enum,避免隐式转换和命名冲突。

代码示例

enum class Color {
    Red, Green };
int main() {
   
    Color c = Color::Red;
    // int x = c;  // 错误,需显式转换
}

15. C++中std::atomic的内存序有哪些?

答案解析

  • memory_order_relaxed:无序。
  • memory_order_acquire/release:获取/释放。
  • memory_order_seq_cst:顺序一致(默认)。

代码示例

#include <atomic>
std::atomic<int> x(0);
void thread1() {
    x.store(1, std::memory_order_release); }
void thread2() {
    int val = x.load(std::memory_order_acquire); }

16. C++中如何实现自定义删除器?

答案解析
智能指针支持自定义删除器,通过lambda或函数指针传入。

代码示例

#include <memory>
void deleter(int* p) {
    std::cout << "Delete\n"; delete p; }
int main() {
   
    std::unique_ptr<int, void(*)(int*)> p(new int, deleter);
}

17. 什么是完美转发?如何实现?

答案解析
完美转发通过std::forward和通用引用(T&&)保持参数的值类别(左值/右值)。

代码示例

template<typename T>
void wrapper(T&& arg) {
   
    func(std::forward<T>(arg));
}

18. C++中std::future和std::promise的区别?

答案解析

  • std::promise:设置异步结果。
  • std::future:获取异步结果。

代码示例

#include <future>
void task(std::promise<int> p) {
    p.set_value(42); }
int main() {
   
    std::promise<int> p;
    std::future<int> f = p.get_future();
    std::thread t(task, std::move(p));
    std::cout << f.get() << "\n";  // 输出: 42
    t.join();
}

19. C++中如何避免虚函数表开销?

答案解析

  • 使用final关键字避免虚函数调用。
  • 静态多态(如CRTP)替代动态多态。

代码示例

class Base {
   
public:
    virtual void func() final {
    std::cout << "Base\n"; }
};

20. C++中如何实现线程池?

答案解析
线程池通过任务队列和固定线程实现任务调度。

代码示例

#include <queue>
#include <thread>
class ThreadPool {
   
    std::vector<std::thread> workers;
    std::queue<std::function<void()>> tasks;
    std::mutex mtx;
    std::condition_variable cv;
    bool stop = false;
public:
    ThreadPool(int n) {
   
        for (int i = 0; i < n; i++)
            workers.emplace_back([this] {
   
                while (true) {
   
                    std::function<void()> task;
                    {
   
                        std::unique_lock<std::mutex> lock(mtx);
                        cv.wait(lock, [this] {
    return stop || !tasks.empty(); });
                        if (stop && tasks.empty()) return;
                        task = std::move(tasks.front());
                        tasks.pop();
                    }
                    task();
                }
            });
    }
    void addTask(std::function<void()> t) {
   
        std::lock_guard<std::mutex> lock(mtx);
        tasks.push(t);
        cv.notify_one();
    }
    ~ThreadPool() {
   
        {
   
            std::lock_guard<std::mutex> lock(mtx);
            stop = true;
        }
        cv.notify_all();
        for (auto& w : workers) w.join();
    }
};

21. C++中如何实现动态多态和静态多态的结合?

答案解析
通过虚函数和CRTP结合实现。

代码示例

template<typename T>
class Base {
   
public:
    void call() {
    static_cast<T*>(this)->impl(); }
    virtual void func() = 0;
};

class Derived : public Base<Derived> {
   
public:
    void impl() {
    std::cout << "Static\n"; }
    void func() override {
    std::cout << "Dynamic\n"; }
};

22. C++中如何实现自定义迭代器?

答案解析
定义符合迭代器trait的类,包含*++等操作。

代码示例

class MyIter {
   
    int* ptr;
public:
    MyIter(int* p) : ptr(p) {
   }
    int& operator*() {
    return *ptr; }
    MyIter& operator++() {
    ptr++; return *this; }
    bool operator!=(const MyIter& other) {
    return ptr != other.ptr; }
};

23. C++中如何实现类型擦除?

答案解析
通过基类接口和虚函数隐藏具体类型。

代码示例

class Any {
   
    struct Base {
   
        virtual ~Base() {
   }
    };
    template<typename T>
    struct Derived : Base {
   
        T value;
        Derived(T v) : value(v) {
   }
    };
    std::unique_ptr<Base> ptr;
public:
    template<typename T>
    Any(T v) : ptr(new Derived<T>(v)) {
   }
};

24. C++中std::optional的作用是什么?

答案解析
std::optional表示可能为空的值,避免非法访问。

代码示例

#include <optional>
std::optional<int> getValue(bool flag) {
   
    if (flag) return 42;
    return {
   };
}
int main() {
   
    auto val = getValue(false);
    if (val) std::cout << *val << "\n";
    else std::cout << "Empty\n";  // 输出: Empty
}

25. C++中如何实现线程安全的日志系统?

答案解析
使用互斥锁或无锁队列保护日志写入。

代码示例

class Logger {
   
    std::mutex mtx;
public:
    void log(const std::string& msg) {
   
        std::lock_guard<std::mutex> lock(mtx);
        std::cout << msg << "\n";
    }
};

26. C++中如何实现自定义内存分配器?

答案解析
重载operator new或实现std::allocator接口。

代码示例

class MyAlloc {
   
public:
    static void* operator new(size_t size) {
   
        std::cout << "Custom alloc\n";
        return ::operator new(size);
    }
    static void operator delete(void* p) {
   
        std::cout << "Custom free\n";
        ::operator delete(p);
    }
};

27. C++中std::variant的作用是什么?

答案解析
std::variant存储多种类型之一的值,类型安全替代union。

代码示例

#include <variant>
int main() {
   
    std::variant<int, std::string> v = 42;
    if (auto p = std::get_if<int>(&v)) std::cout << *p << "\n";  // 输出: 42
}

28. C++中如何实现异常安全的代码?

答案解析
使用RAII和强异常保证(操作失败不改变状态)。

代码示例

class Safe {
   
    std::vector<int> data;
public:
    void add(int x) {
   
        std::vector<int> temp = data;  // 备份
        temp.push_back(x);
        data.swap(temp);  // 无异常交换
    }
};

29. C++中如何实现协程(C++20)?

答案解析
C++20引入co_awaitco_yield等支持协程。

代码示例

#include <coroutine>
struct Task {
   
    struct promise_type {
   
        Task get_return_object() {
    return {
   }; }
        std::suspend_never initial_suspend() {
    return {
   }; }
        std::suspend_never final_suspend() noexcept {
    return {
   }; }
        void return_void() {
   }
        void unhandled_exception() {
   }
    };
};

Task coro() {
   
    std::cout << "Coro\n";
    co_return;
}

30. C++中如何实现单向链表的反转?

答案解析
使用三个指针迭代反转指针方向。

代码示例

struct Node {
   
    int val;
    Node* next;
};

Node* reverseList(Node* head) {
   
    Node *prev = nullptr, *curr = head, *next;
    while (curr) {
   
        next = curr->next;
        curr->next = prev;
        prev = curr;
        curr = next;
    }
    return prev;
}

31. C++中如何实现RTTI?

答案解析
RTTI(Run-Time Type Information)通过typeiddynamic_cast实现。

代码示例

#include <typeinfo>
class Base {
    virtual ~Base() {
   } };
class Derived : public Base {
   };
int main() {
   
    Base* b = new Derived();
    std::cout << typeid(*b).name() << "\n";  // 输出: Derived
    delete b;
}

32. C++中如何实现线程安全的队列?

答案解析
使用互斥锁和条件变量保护队列操作。

代码示例

#include <queue>
template<typename T>
class SafeQueue {
   
    std::queue<T> q;
    std::mutex mtx;
    std::condition_variable cv;
public:
    void push(T val) {
   
        std::lock_guard<std::mutex> lock(mtx);
        q.push(val);
        cv.notify_one();
    }
    T pop() {
   
        std::unique_lock<std::mutex> lock(mtx);
        cv.wait(lock, [this] {
    return !q.empty(); });
        T val = q.front();
        q.pop();
        return val;
    }
};

33. C++中std::enable_if的典型用法?

答案解析
std::enable_if用于模板条件编译,控制函数重载。

代码示例

template<typename T, std::enable_if_t<std::is_floating_point_v<T>, int> = 0>
void func(T) {
    std::cout << "Float\n"; }

34. C++中如何实现动态数组的扩容?

答案解析
重新分配内存并拷贝数据,类似std::vector

代码示例

class DynArray {
   
    int* data;
    size_t size, capacity;
public:
    DynArray() : data(nullptr), size(0), capacity(0) {
   }
    void push_back(int val) {
   
        if (size == capacity) {
   
            capacity = capacity ? capacity * 2 : 1;
            int* temp = new int[capacity];
            std::copy(data, data + size, temp);
            delete[] data;
            data = temp;
        }
        data[size++] = val;
    }
    ~DynArray() {
    delete[] data; }
};

35. C++中如何实现工厂模式?

答案解析
工厂模式通过基类指针创建具体对象。

代码示例

class Product {
   
public:
    virtual void use() = 0;
};

class ConcreteProduct : public Product {
   
public:
    void use() override {
    std::cout << "Concrete\n"; }
};

class Factory {
   
public:
    static std::unique_ptr<Product> create() {
   
        return std::make_unique<ConcreteProduct>();
    }
};

36. C++中如何实现观察者模式?

答案解析
观察者模式通过主体通知观察者实现松耦合。

代码示例

#include <vector>
class Observer {
   
public:
    virtual void update(int) = 0;
};

class Subject {
   
    std::vector<Observer*> observers;
public:
    void attach(Observer* o) {
    observers.push_back(o); }
    void notify(int state) {
   
        for (auto o : observers) o->update(state);
    }
};

37. C++中如何实现内存池?

答案解析
内存池预分配固定大小块,按需分配。

代码示例

class MemPool {
   
    std::vector<char*> blocks;
    size_t block_size, count;
public:
    MemPool(size_t size, size_t n) : block_size(size), count(n) {
   
        char* mem = new char[size * n];
        for (size_t i = 0; i < n; i++) blocks.push_back(mem + i * size);
    }
    void* alloc() {
    return blocks.empty() ? nullptr : blocks.back(); blocks.pop_back(); }
    ~MemPool() {
    delete[] blocks[0]; }
};

38. C++中std::chrono的典型用法?

答案解析
std::chrono用于时间测量和操作。

代码示例

#include <chrono>
int main() {
   
    auto start = std::chrono::high_resolution_clock::now();
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
    auto end = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
    std::cout << duration.count() << "ms\n";
}

39. C++中如何实现无锁队列?

答案解析
使用std::atomic实现无锁操作。

代码示例

#include <atomic>
template<typename T>
class LockFreeQueue {
   
    struct Node {
   
        T data;
        std::atomic<Node*> next;
        Node(T d) : data(d), next(nullptr) {
   }
    };
    std::atomic<Node*> head, tail;
public:
    LockFreeQueue() {
    Node* dummy = new Node(T()); head = tail = dummy; }
    void push(T val) {
   
        Node* node = new Node(val);
        Node* t;
        do {
   
            t = tail.load();
            node->next = nullptr;
        } while (!tail.compare_exchange_strong(t, node));
    }
};

40. C++中如何实现自定义哈希函数?

答案解析
std::unordered_map提供哈希函数。

代码示例

struct MyKey {
   
    int id;
};

struct MyHash {
   
    size_t operator()(const MyKey& k) const {
    return std::hash<int>{
   }(k.id); }
};

std::unordered_map<MyKey, int, MyHash> map;

41. C++中如何实现深拷贝?

答案解析
通过拷贝构造函数或赋值运算符实现深拷贝。

代码示例

class Deep {
   
    int* data;
public:
    Deep(int v) : data(new int(v)) {
   }
    Deep(const Deep& other) : data(new int(*other.data)) {
   }
    ~Deep() {
    delete data; }
};

42. C++中如何实现单例模式的懒汉式?

答案解析
延迟初始化,使用静态局部变量(C++11线程安全)。

代码示例

class Singleton {
   
    Singleton() {
   }
public:
    static Singleton& getInstance() {
   
        static Singleton instance;
        return instance;
    }
};

43. C++中std::tuple的用法?

答案解析
std::tuple存储异构数据,支持std::get访问。

代码示例

#include <tuple>
int main() {
   
    std::tuple<int, std::string> t(42, "hello");
    std::cout << std::get<0>(t) << " " << std::get<1>(t) << "\n";
}

44. C++中如何实现编译期类型检查?

答案解析
使用static_assert检查类型条件。

代码示例

template<typename T>
void func() {
   
    static_assert(std::is_integral_v<T>, "T must be integral");
}

45. C++中如何实现多态的类型擦除容器?

答案解析
通过基类接口和智能指针实现。

代码示例

class AnyContainer {
   
    struct Base {
   
        virtual ~Base() {
   }
    };
    template<typename T>
    struct Derived : Base {
   
        T value;
        Derived(T v) : value(v) {
   }
    };
    std::unique_ptr<Base> ptr;
public:
    template<typename T>
    void push(T v) {
    ptr = std::make_unique<Derived<T>>(v); }
};

46. C++中如何实现高效的字符串拼接?

答案解析
使用std::string::reserve预分配空间。

代码示例

std::string concat(const std::vector<std::string>& vec) {
   
    std::string res;
    size_t total = 0;
    for (const auto& s : vec) total += s.size();
    res.reserve(total);
    for (const auto& s : vec) res += s;
    return res;
}

47. C++中如何实现线程安全的栈?

答案解析
使用互斥锁保护栈操作。

代码示例

template<typename T>
class SafeStack {
   
    std::stack<T> s;
    std::mutex mtx;
public:
    void push(T val) {
   
        std::lock_guard<std::mutex> lock(mtx);
        s.push(val);
    }
    T pop() {
   
        std::lock_guard<std::mutex> lock(mtx);
        T val = s.top();
        s.pop();
        return val;
    }
};

48. C++中如何实现依赖注入?

答案解析
通过构造函数或接口注入依赖。

代码示例

class Service {
   
public:
    virtual void serve() = 0;
};

class ConcreteService : public Service {
   
public:
    void serve() override {
    std::cout << "Serving\n"; }
};

class Client {
   
    std::unique_ptr<Service> service;
public:
    Client(std::unique_ptr<Service> s) : service(std::move(s)) {
   }
    void run() {
    service->serve(); }
};

49. C++中std::filesystem的典型用法?

答案解析
C++17的std::filesystem用于文件操作。

代码示例

#include <filesystem>
int main() {
   
    std::filesystem::create_directory("test");
    std::filesystem::path p = "test/file.txt";
    std::ofstream(p) << "Hello";
}

50. C++中如何实现高效的内存对齐?

答案解析
使用alignas或手动调整内存分配。

代码示例

struct alignas(16) Aligned {
   
    int x;
};
void* alignedAlloc(size_t size, size_t align) {
   
    void* p = nullptr;
    return std::align(align, size, p, size) ? p : nullptr;
}

51. C++中std::vector的容量增长策略是什么?

答案解析
std::vector的容量通常按倍增(如2倍)增长,以摊销插入成本。

  • 插入时若大小超过容量,重新分配更大内存并拷贝数据。
  • 可通过reserve预分配减少重分配。

代码示例

#include <vector>
int main() {
   
    std::vector<int> v;
    v.reserve(100);  // 预分配
    std::cout << v.capacity() << "\n";  // 输出: 100
    v.push_back(1);  // 无重分配
}

52. 如何在C++中实现线程安全的对象池?

答案解析
使用互斥锁保护对象分配和回收。

代码示例

#include <mutex>
#include <queue>
template<typename T>
class ObjectPool {
   
    std::queue<T*> pool;
    std::mutex mtx;
public:
    T* acquire() {
   
        std::lock_guard<std::mutex> lock(mtx);
        if (pool.empty()) return new T();
        T* obj = pool.front();
        pool.pop();
        return obj;
    }
    void release(T* obj) {
   
        std::lock_guard<std::mutex> lock(mtx);
        pool.push(obj);
    }
};

53. C++中如何实现编译期斐波那契数列?

答案解析
使用模板元编程在编译期递归计算。

代码示例

template<int N>
struct Fib {
   
    static const int value = Fib<N-1>::value + Fib<N-2>::value;
};
template<> struct Fib<0> {
    static const int value = 0; };
template<> struct Fib<1> {
    static const int value = 1; };

int main() {
   
    std::cout << Fib<10>::value << "\n";  // 输出: 55
}

54. C++中如何实现高效的红黑树?

答案解析
红黑树需维护颜色和平衡规则,可借助std::set或手动实现。

代码示例(简版):

enum Color {
    RED, BLACK };
struct RBNode {
   
    int val;
    Color color;
    RBNode *left, *right, *parent;
    RBNode(int v) : val(v), color(RED), left(nullptr), right(nullptr), parent(nullptr) {
   }
};

class 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天涯学馆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值