极限c++模拟卷
C++ 模拟试卷(一)
一、选择题(每题 3 分,共 30 分)
-
以下关于 C++ 指针和引用的描述,错误的是( )
A. 指针可以为空,引用必须初始化且不能引用空值
B. 指针需要解引用访问值,引用可直接当作原变量使用
C. 指针的类型是存储地址的变量,引用是变量的别名
D. 指针和引用都支持自增、自减操作 -
关于 C++ 类的构造函数,说法正确的是( )
A. 构造函数必须有返回值类型
B. 一个类只能有一个构造函数
C. 构造函数可以用const
修饰
D. 构造函数用于初始化对象成员 -
以下实现多态的核心条件是( )
A. 函数重载
B. 基类指针或引用指向派生类对象,且基类函数为虚函数
C. 派生类重新定义基类的非虚函数
D. 类模板的实例化 -
关于
unique_ptr
和shared_ptr
的区别,错误的是( )
A.unique_ptr
独占对象所有权,shared_ptr
共享所有权
B.unique_ptr
可通过make_unique
创建,shared_ptr
可通过make_shared
创建
C.shared_ptr
存在循环引用风险,unique_ptr
不存在
D.unique_ptr
和shared_ptr
都支持拷贝构造 -
以下代码中,拷贝构造函数会被调用的场景是( )
cpp
运行
class Test { /* 省略成员 */ };
void func(Test obj) { /* ... */ }
int main() {Test t1;Test t2 = t1; func(t1); return Test();
}
A. 仅 Test t2 = t1;
B. Test t2 = t1;
和 func(t1);
C. 三者都会
D. Test t2 = t1;
、func(t1);
和 return Test();
-
关于 C++ 模板,说法正确的是( )
A. 函数模板的类型参数只能是内置类型
B. 类模板实例化时无需指定类型参数
C. 模板特化可以为特定类型定制逻辑
D. 模板代码在编译时不会生成具体代码 -
以下会导致内存泄漏的是( )
A. 使用unique_ptr
管理动态分配对象
B.new
分配内存后未调用delete
C. 使用shared_ptr
共享对象所有权
D. 局部变量的普通指针指向堆内存 -
虚函数的实现依赖于( )
A. 函数重载机制
B. 虚函数表(vtable)和虚表指针(vptr)
C. 模板特化
D. 预处理指令 -
派生类覆盖基类虚函数时,以下必须满足的条件是( )
A. 函数名相同即可
B. 函数参数、返回值必须与基类虚函数完全一致(协变返回值除外)
C. 派生类函数需用virtual
显式声明
D. 基类函数不能是纯虚函数 -
以下关于异常处理的描述,正确的是( )
A.try
块中只能抛出一种类型的异常
B.catch(...)
必须放在所有catch
块的最前面
C. 异常对象抛出后,会被第一个匹配的catch
块捕获
D. 自定义异常类无需继承std::exception
二、简答题(每题 8 分,共 40 分)
- 简述 C++ 中指针和引用的核心区别(至少 3 点)。
- 说明虚函数的实现原理(虚函数表和虚表指针的作用)。
- 列举 3 种会调用拷贝构造函数的场景。
- 什么是内存泄漏?写出两种避免内存泄漏的方法。
- 区分函数重载(overload)和函数覆盖(override)的关键差异。
三、编程题(每题 15 分,共 30 分)
-
定义一个
Circle
类,包含私有成员radius
(半径),实现:- 构造函数初始化半径;
- 计算面积的成员函数(
double getArea()
); - 重载
<<
运算符,输出Circle(radius)
格式的字符串。
-
基于多态实现以下需求:
- 定义抽象基类
Shape
,包含纯虚函数draw()
; - 派生
Rectangle
类和Triangle
类,分别实现draw()
输出矩形、三角形的绘制描述; - 在
main
中用基类指针数组存储派生类对象,遍历调用draw()
。
- 定义抽象基类
C++ 模拟试卷(二)
一、选择题(每题 3 分,共 30 分)
-
以下对 C++ 引用的描述,正确的是( )
A. 引用是一种指针常量,不能修改指向
B. 引用可以绑定到空值(nullptr
)
C. 引用的大小等于指针的大小
D. 同一变量可以有多个引用,且引用间相互独立 -
关于类的析构函数,说法错误的是( )
A. 析构函数名与类名相同,前面加~
B. 析构函数无参数、无返回值
C. 一个类只能有一个析构函数
D. 析构函数用于初始化对象成员 -
多态中,基类指针指向派生类对象时,调用的函数由( )决定。
A. 指针的类型(编译时)
B. 对象的实际类型(运行时)
C. 函数的访问权限
D. 函数是否为内联函数 -
以下智能指针使用正确的是( )
A.unique_ptr<int> p1 = new int(10);
B.shared_ptr<int> p2 = p1;
(p1
是unique_ptr
)
C.weak_ptr<int> p3 = make_shared<int>(20);
D.shared_ptr<int> p4 = make_shared<int>(30);
-
拷贝构造函数的参数必须是( )
A. 类对象的值传递
B. 类对象的指针
C. 类对象的常引用(const 类名&
)
D. 任意类型 -
函数模板
template <typename T> T add(T a, T b)
,以下调用错误的是( )
A.add(1, 2);
B.add(3.14, 2.71);
C.add(5, 3.5);
(未显式指定类型)
D.add<int>(6, 7.8);
-
以下不会导致内存泄漏的是( )
A.int* p = new int[10];
后未delete[] p;
B. 使用shared_ptr
管理动态数组
C. 函数返回栈对象的指针
D.malloc(100);
后未free
-
虚函数表(vtable)存储的是( )
A. 类的所有成员函数地址
B. 类的虚函数地址
C. 对象的成员变量值
D. 类的静态成员函数地址 -
派生类覆盖基类虚函数时,
override
关键字的作用是( )
A. 必须使用,否则无法覆盖
B. 可选,用于显式标记重写,编译器会检查是否匹配基类虚函数
C. 用于将函数声明为虚函数
D. 用于改变函数的访问权限 -
异常处理中,
catch(...)
的作用是( )
A. 捕获所有类型的异常
B. 捕获未被其他catch
块匹配的异常
C. 必须放在catch
块的最前面
D. 只能捕获自定义异常
二、简答题(每题 8 分,共 40 分)
- 说明 C++ 中构造函数、拷贝构造函数、析构函数的典型作用。
- 简述智能指针
unique_ptr
、shared_ptr
、weak_ptr
的适用场景。 - 解释多态的 “动态绑定” 机制,并举简单代码示例。
- 什么是模板特化?写出一个函数模板全特化的示例。
- 如何避免派生类覆盖基类虚函数时的 “意外重载”(提示:
override
关键字)?
三、编程题(每题 15 分,共 30 分)
-
实现一个
String
类(简化版),包含:- 私有成员
char* data
(存储字符串); - 构造函数(支持
const char*
初始化); - 拷贝构造函数(深拷贝,避免浅拷贝问题);
- 析构函数(释放
data
内存); - 重载
+
运算符,实现字符串拼接。
- 私有成员
-
用线程和
async
实现以下需求:- 定义函数
longTimeTask()
,模拟耗时操作(sleep
几秒后输出 “任务完成”); - 用
async
启动异步任务,获取future
对象; - 主线程先执行其他逻辑(如输出 “等待任务...”),再通过
future.get()
等待任务完成。
- 定义函数
C++ 模拟试卷(三)
一、选择题(每题 3 分,共 30 分)
-
以下关于 C++ 指针的描述,错误的是( )
A. 指针可以指向不同类型的变量(通过强制类型转换)
B. 野指针是指向已释放或非法地址的指针
C.void*
指针可以直接解引用访问值
D. 指针数组存储的是多个指针的地址 -
类的静态成员的特点是( )
A. 每个对象有独立的静态成员副本
B. 静态成员函数没有this
指针
C. 静态成员只能被静态成员函数访问
D. 静态成员必须在类内初始化 -
多态中,纯虚函数的作用是( )
A. 实现接口约束,强制派生类实现
B. 提高函数调用效率
C. 允许函数重载
D. 用于模板特化 -
以下
shared_ptr
导致循环引用的场景是( )
cpp
运行
class A { public: shared_ptr<B> b; };
class B { public: shared_ptr<A> a; };
int main() {auto a = make_shared<A>();auto b = make_shared<B>();a->b = b;b->a = a;return 0;
}
A. 不会循环引用
B. a
和 b
的引用计数无法减为 0,导致内存泄漏
C. 编译报错
D. 运行时崩溃
-
拷贝构造函数与赋值运算符重载的区别是( )
A. 拷贝构造函数初始化新对象,赋值运算符重载给已存在对象赋值
B. 拷贝构造函数有返回值,赋值运算符重载没有
C. 拷贝构造函数参数是对象,赋值运算符重载参数是常引用
D. 拷贝构造函数只能有一个,赋值运算符重载可以有多个 -
函数模板的实例化方式是( )
A. 手动实例化(显式指定类型)
B. 自动实例化(编译器推导类型)
C. 以上两种都可以
D. 只能在运行时实例化 -
以下异常处理代码,正确的执行流程是( )
cpp
运行
try {throw runtime_error("出错");
} catch (const exception& e) {cout << "捕获 exception: " << e.what();
} catch (const runtime_error& e) {cout << "捕获 runtime_error: " << e.what();
}
A. 先匹配 runtime_error
,输出 “捕获 runtime_error: 出错”
B. 先匹配 exception
,输出 “捕获 exception: 出错”
C. 编译报错(catch
顺序错误)
D. 运行时崩溃
-
虚函数表属于( )
A. 类的对象
B. 类本身(所有对象共享)
C. 函数的作用域
D. 模板的实例 -
派生类覆盖基类虚函数时,以下必须一致的是( )
A. 函数名、返回值类型、参数列表
B. 函数名、参数列表(返回值协变除外)
C. 函数名、访问权限
D. 函数名、是否为静态函数 -
以下关于
async
和thread
的区别,正确的是( )
A.async
一定创建新线程,thread
不一定
B.async
返回future
获取结果,thread
需手动管理同步
C.async
只能执行无返回值任务,thread
可以执行有返回值任务
D.async
无需包含头文件,thread
需要
二、简答题(每题 8 分,共 40 分)
- 说明静态成员与非静态成员的核心区别(至少 3 点)。
- 如何用
weak_ptr
解决shared_ptr
的循环引用问题?写简单示例。 - 解释 C++ 中的 “动态绑定” 和 “静态绑定”,各举一个代码场景。
- 模板特化的作用是什么?对比函数重载和模板特化的差异。
- 异常处理中,
throw
、try
、catch
的协作流程是怎样的?
三、编程题(每题 15 分,共 30 分)
-
实现一个线程安全的计数器类
Counter
,包含:- 私有成员
int count
; - 线程安全的
increment()
函数(用mutex
保护); - 线程安全的
getCount()
函数; - 用
thread
创建多个线程,并发调用increment()
,验证线程安全。
- 私有成员
-
用类模板实现一个通用的 “队列”(
Queue
),支持:push(T val)
:向队列尾部添加元素;pop()
:移除并返回队列头部元素(处理空队列异常);isEmpty()
:判断队列是否为空;- 在
main
中实例化Queue<int>
,测试功能。
答案提示(核心得分点)
- 选择题:结合知识点速记,重点区分指针引用、多态、智能指针、异常等概念。
- 简答题:抓关键词(如 “虚函数表”“拷贝场景”“内存泄漏避免方法” )。
- 编程题:
- 类设计需包含构造、析构、运算符重载;
- 多态必须用虚函数 + 基类指针;
- 线程安全需用
mutex
或智能指针; - 模板代码需正确写
template
声明。
考试时优先保证代码框架正确,再补细节,祝高分通过!