一、练习题部分
█ 基础语法(20分)
-
下面代码输出什么?
int main() {
int a = 5;
cout << (a++ + ++a) << endl;
return 0;
}
2.请写出const int*
、int const*
和int* const
的区别
3.以下代码存在什么问题?
char* func() {
char str[] = "hello";
return str;
}
█ 面向对象(25分)
-
实现一个不可继承的
FinalClass
-
虚函数表(vtable)在什么阶段创建?每个类的虚表有几个?
-
写出下面代码输出:
class Base {
public:
virtual void show() { cout << "Base" << endl; }
};
class Derived : public Base {
public:
void show() override { cout << "Derived" << endl; }
};
int main() {
Base* obj = new Derived();
obj->show();
delete obj;
return 0;
}
█ 模板与STL(20分)
-
实现通用的数组打印函数模板
printArray
-
下面代码的时间复杂度是多少?
vector<int> vec(1000000);
for(auto it = vec.begin(); it != vec.end(); ++it) {
// 操作
}
3.使用std::unique_ptr
改写以下代码:
MyClass* obj = new MyClass();
obj->process();
delete obj;
█ 高级特性(35分)
-
实现线程安全的单例模式
-
解释移动语义并给出应用示例
-
使用lambda表达式实现vector排序:
vector<pair<int, string>> vec = {{2,"b"}, {1,"a"}};
// 按第一个元素降序排列
4.处理以下异常场景:
try {
throw "Unknown error";
} catch(...) {
// 如何获取异常信息?
}
█ 综合编程(20分)
-
实现二叉树层序遍历
-
编写生产者-消费者模型(使用C++11线程库)
二、参考答案
基础语法
-
答案:输出结果不确定(未定义行为)
解析:表达式中的变量多次修改导致UB -
答案:
-
const int*
:指向常量的指针 -
int const*
:同上 -
int* const
:常量指针(不可修改指向)
-
-
答案:返回局部变量的地址(悬垂指针)
面向对象
-
答案:
class FinalClass final {};
2.答案:编译期创建,每个类一个虚表
答案:输出"Derived"
模板与STL
-
答案:
template<typename T, size_t N>
void printArray(T (&arr)[N]) {
for(const auto& item : arr) {
cout << item << " ";
}
}
-
答案:
O(n)
3.答案:
auto obj = std::make_unique<MyClass>();
obj->process();
高级特性
-
答案:
class Singleton {
private:
static std::mutex mtx;
static Singleton* instance;
Singleton() = default;
public:
static Singleton* getInstance() {
std::lock_guard<std::mutex> lock(mtx);
if(!instance) {
instance = new Singleton();
}
return instance;
}
};
2.答案示例:
vector<string> v1 = {"a", "b"};
vector<string> v2 = std::move(v1); // 移动语义
3.答案:
sort(vec.begin(), vec.end(),
[](const auto& a, const auto& b) {
return a.first > b.first;
});
4.答案:
catch(const std::exception& e) {
cout << e.what();
} catch(...) {
cout << "Unknown exception";
}
综合编程
-
答案框架:
void levelOrder(TreeNode* root) {
queue<TreeNode*> q;
q.push(root);
while(!q.empty()) {
// 处理当前层节点
}
}
2.答案要点:
-
使用
std::mutex
和std::condition_variable
-
维护共享队列
-
生产者
push
数据并通知 -
消费者
wait
并处理数据
例子:
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>
#include <vector>
// 共享资源
std::queue<int> queue;
std::mutex mtx;
std::condition_variable cv;
bool finished = false; // 标记生产者是否完成生产
// 生产者函数
void producer(int id, int items) {
for (int i = 0; i < items; ++i) {
std::unique_lock<std::mutex> lock(mtx);
queue.push(i);
std::cout << "Producer " << id << " produced " << i << std::endl;
lock.unlock();
cv.notify_one(); // 通知消费者
}
}
// 消费者函数
void consumer(int id) {
while (true) {
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, []{ return !queue.empty() || finished; }); // 等待条件满足
if (finished && queue.empty()) {
break; // 如果生产者完成生产且队列为空,则退出
}
int item = queue.front();
queue.pop();
std::cout << "Consumer " << id << " consumed " << item << std::endl;
lock.unlock();
}
}
int main() {
const int num_producers = 2;
const int num_consumers = 2;
const int items_per_producer = 5;
std::vector<std::thread> producers;
std::vector<std::thread> consumers;
// 创建生产者线程
for (int i = 0; i < num_producers; ++i) {
producers.emplace_back(producer, i, items_per_producer);
}
// 创建消费者线程
for (int i = 0; i < num_consumers; ++i) {
consumers.emplace_back(consumer, i);
}
// 等待所有生产者完成
for (auto& p : producers) {
p.join();
}
// 设置完成标记并通知所有消费者
{
std::unique_lock<std::mutex> lock(mtx);
finished = true;
}
cv.notify_all();
// 等待所有消费者完成
for (auto& c : consumers) {
c.join();
}
return 0;
}
三、评分标准
等级划分(总分120分)
-
A(≥100分):精通C++核心特性,具备工程级开发能力
-
B(80-99分):熟练掌握C++,可承担复杂模块开发
-
C(60-79分):基础扎实,需加强高级特性实践
-
D(<60分):需要系统复习语言特性
四、学习建议
-
重点复习对象生命周期管理
-
掌握现代C++智能指针用法
-
加强多线程编程实践
-
深入理解模板元编程
请根据实际答题情况查漏补缺,建议结合《Effective C++》等经典书籍进行系统学习。