Skip to content

C++相关题目

单选题

S01. 单选题

C++ 中多态的核心机制通常是?

A. 宏替换 B. 虚函数表和虚表指针 C. 命名空间 D. 预编译头

答案:B

解析:运行时多态常由 vptr/vtable 实现,基类指针或引用调用虚函数时根据动态类型分派。

题目图示

S02. 单选题

通过基类指针 delete 派生类对象,基类析构函数应该?

A. 设为 virtual B. 设为 static C. 设为 inline 即可 D. 设为 private 一定正确

答案:A

解析:需要多态删除时,基类析构应为 virtual,否则派生资源可能不释放。

题目图示

S03. 单选题

std::move 的作用是?

A. 立即搬移内存 B. 把对象转换成右值表达式 C. 删除对象 D. 复制对象

答案:B

解析:std::move 本身只是类型转换,真正移动发生在移动构造或移动赋值。

题目图示

S04. 单选题

vector 扩容后一定失效的是?

A. 旧元素指针和迭代器 B. 所有 int 值 C. vector 类型本身 D. 编译器

答案:A

解析:扩容重新分配连续内存,旧存储上的指针、引用、迭代器失效。

题目图示

S05. 单选题

map 和 unordered_map 的主要区别是?

A. map 有序,unordered_map 哈希无序 B. 二者都保证有序 C. map 只能存 int D. unordered_map 查询一定 O(log n)

答案:A

解析:map 常基于红黑树,按 key 有序;unordered_map 基于哈希表,平均 O(1),不保证顺序。

题目图示

S06. 单选题

以下哪项最符合 RAII?

A. 资源生命周期绑定对象生命周期 B. 所有资源都用全局变量 C. 析构时永不释放 D. 只用于图形学

答案:A

解析:RAII 在构造获取资源、析构释放资源,是 C++ 异常安全的基础。

题目图示

S07. 单选题

new/delete 与 malloc/free 的区别不包括?

A. new 会调用构造函数 B. delete 会调用析构函数 C. malloc 返回 void* D. malloc 会自动调用 C++ 构造函数

答案:D

解析:malloc 只分配原始内存,不调用构造函数。

题目图示

S08. 单选题

const 成员函数中,普通成员变量默认?

A. 不能修改 B. 必须修改 C. 会自动变 static D. 只能在堆上修改

答案:A

解析:const 成员函数中的 this 指针是指向 const 对象的指针,普通成员不可改。

题目图示

S09. 单选题

浅拷贝最容易导致的问题是?

A. 两个对象共享同一资源并重复释放 B. 代码变快 C. 无法编译任何程序 D. 变量名变短

答案:A

解析:含裸指针资源的类若默认浅拷贝,析构时可能双重释放。

题目图示

S10. 单选题

C++ 中 static 局部变量的生命周期是?

A. 整个程序运行期间 B. 当前表达式 C. 当前 if 块 D. 只在编译期

答案:A

解析:static 局部变量具有静态存储期,只初始化一次,生命周期到程序结束。

题目图示

S11. 单选题

函数重载主要依据什么区分?

A. 参数列表 B. 返回值类型 C. 注释 D. 文件名

答案:A

解析:C++ 函数重载看函数名和参数列表;仅返回值不同不能构成重载。

题目图示

S12. 单选题

模板声明和实现通常为什么放头文件?

A. 编译实例化需要看到定义 B. 头文件运行更快 C. cpp 文件不能写模板 D. 模板不能有实现

答案:A

解析:模板在实例化时需要完整定义,常放头文件。

题目图示

S13. 单选题

以下哪个容器插入/删除中间节点通常不会导致其他迭代器失效?

A. list B. vector C. deque 所有情况 D. string

答案:A

解析:list 节点独立分配,插入删除通常只影响被删除元素。

题目图示

S14. 单选题

unordered_map rehash 后会发生什么?

A. 桶重建,迭代器可能失效 B. 自动排序 C. 所有 key 变成 0 D. 变成 vector

答案:A

解析:rehash 会重建桶数组并重新分布元素。

题目图示

S15. 单选题

C++ 中引用必须?

A. 定义时初始化 B. 可以随时改绑定对象 C. 一定占 0 字节 D. 只能引用临时变量

答案:A

解析:引用是别名,必须初始化,之后不能重新绑定。

题目图示

S16. 单选题

lambda 默认按值捕获时,外部变量在 lambda 内部默认?

A. 只读副本 B. 引用原对象 C. 会被删除 D. 变成 static

答案:A

解析:按值捕获复制变量;若要修改副本需 mutable,外部值不变。

题目图示

S17. 单选题

atomic 主要解决什么问题?

A. 无锁原子读改写 B. 图形渲染 C. 压缩图片 D. 替代所有算法

答案:A

解析:atomic 用于原子操作和内存序控制,避免数据竞争。

题目图示

S18. 单选题

mutex 的主要作用是?

A. 保护临界区 B. 提高显卡显存 C. 替代类继承 D. 自动优化 SQL

答案:A

解析:互斥锁保证同一时间只有一个线程进入临界区。

题目图示

S19. 单选题

条件变量 condition_variable 通常配合什么使用?

A. mutex 和谓词条件 B. delete[] C. 纹理采样 D. 宏定义

答案:A

解析:条件变量等待条件变化,需要互斥锁保护共享状态,并用谓词避免虚假唤醒。

题目图示

S33. 单选题

浮点数比较通常不建议直接 ==,原因是?

A. 浮点精度误差 B. float 无法存任何数 C. == 会删除对象 D. 编译器不支持

答案:A

解析:浮点运算存在舍入误差,通常比较差值是否小于 epsilon。

题目图示

S34. 单选题

sizeof 空类对象通常至少为 1,是为了?

A. 保证不同对象有不同地址 B. 让对象无法创建 C. 节省所有内存 D. 禁用继承

答案:A

解析:C++ 要求不同对象可区分,空类对象大小通常为 1。

题目图示

S35. 单选题

结构体内存对齐的主要目的?

A. 提升访问效率并满足平台约束 B. 让代码更短 C. 替代继承 D. 自动加密

答案:A

解析:对齐能让 CPU 更高效访问数据,也满足某些平台的硬件要求。

题目图示

S36. 单选题

inline 与宏相比的优势包括?

A. 有类型检查和作用域规则 B. 一定不生成代码 C. 不能调试 D. 一定比宏慢

答案:A

解析:inline 是函数语义,保留类型检查;宏只是预处理文本替换。

题目图示

S37. 单选题

虚继承主要解决?

A. 菱形继承中公共基类重复子对象问题 B. 网络重传 C. 贴图压缩 D. 哈希冲突

答案:A

解析:虚继承让菱形继承中共享同一份虚基类子对象。

题目图示

S38. 单选题

placement new 的作用是?

A. 在已分配内存上构造对象 B. 自动申请网络连接 C. 释放数组 D. 排序 vector

答案:A

解析:placement new 不分配内存,只在指定地址调用构造函数。

题目图示

S39. 单选题

dynamic_cast 常用于?

A. 多态类型安全向下转型 B. 整数加法 C. 宏展开 D. 文件写入

答案:A

解析:dynamic_cast 对多态类型进行运行时检查,失败返回 null 或抛异常。

题目图示

不定项选择题

M01. 不定项选择题

关于 shared_ptr 正确的有?

A. 引用计数归零释放对象 B. 可能循环引用 C. 可配合 weak_ptr D. 一定比 unique_ptr 更适合所有场景

答案:A、B、C

解析:shared_ptr 表示共享所有权,不适合所有场景。

题目图示

M02. 不定项选择题

哪些属于 STL 关联容器?

A. map B. set C. unordered_map D. vector

答案:A、B、C

解析:map/set 有序关联,unordered_map 是无序关联,vector 是序列容器。

题目图示

M03. 不定项选择题

哪些会导致数据竞争风险?

A. 多个线程写同一变量且无同步 B. 一个线程读一个线程写且无同步 C. 只读共享常量 D. 使用 mutex 保护

答案:A、B

解析:无同步读写共享可变数据会有数据竞争。

题目图示

M04. 不定项选择题

关于右值引用正确的有?

A. 可用于移动语义 B. 形如 T&& C. 命名右值引用变量本身是左值 D. 只能绑定 int

答案:A、B、C

解析:命名变量都是左值,即使类型是 T&&。

题目图示

M05. 不定项选择题

下列哪些是常见未定义行为?

A. 数组越界 B. 解引用空指针 C. 有符号整数溢出 D. vector.size()

答案:A、B、C

解析:这些都可能造成未定义行为,笔试读代码题常考。

题目图示

M08. 不定项选择题

常见线程同步方式包括?

A. mutex B. condition_variable C. atomic D. reinterpret_cast

答案:A、B、C

解析:类型转换不是同步机制。

题目图示

M09. 不定项选择题

可能造成内存泄漏的有?

A. new 后路径提前 return 未 delete B. shared_ptr 循环引用 C. 容器自动析构 D. 异常跳过手动释放

答案:A、B、D

解析:RAII/智能指针能缓解手动释放路径遗漏。

题目图示

M10. 不定项选择题

关于多态正确的有?

A. 虚函数支持动态绑定 B. 纯虚函数可使类成为抽象类 C. 构造函数内虚调用不会分派到派生类 D. 静态函数可以是 virtual

答案:A、B、C

解析:static 成员函数没有 this,不能是虚函数。

题目图示

M19. 不定项选择题

关于 const 正确的有?

A. 可修饰变量 B. 可修饰成员函数 C. 可参与函数重载 D. 等同于宏

答案:A、B、C

解析:const 有类型和作用域,宏只是文本替换。

题目图示

M20. 不定项选择题

关于内存对齐正确的有?

A. 可能产生 padding B. 影响 sizeof C. 提升访问效率 D. static 成员一定算入对象大小

答案:A、B、C

解析:static 成员属于类,不计入单个对象大小。

题目图示

M24. 不定项选择题

哪些可能是代码输出题陷阱?

A. 未定义行为 B. 构造析构顺序 C. 重载决议 D. 注释字数

答案:A、B、C

解析:读代码输出常考 C++ 语义边界。

题目图示

M25. 不定项选择题

关于 cache 友好正确的有?

A. 连续内存通常局部性更好 B. 频繁随机访问可能 miss 多 C. 结构体布局会影响缓存 D. cache 与性能无关

答案:A、B、C

解析:游戏性能优化常关注缓存局部性。

题目图示

代码填空

F04. 代码填空

补全单例。

cpp
class S {
public:
    static S& ins() {
        static /*1*/ obj;
        return obj;
    }
private:
    S()=default;
    S(const S&)=/*2*/;
    S& operator=(const S&)=/*3*/;
};

答案:

cpp
S
delete
delete

解析:局部静态对象懒加载,删除拷贝避免多个实例。

题目图示

F05. 代码填空

补全 RAII 锁。

cpp
class Guard {
    mutex& m;
public:
    Guard(mutex& x):m(x) {
        /*1*/
    }
    ~Guard() {
        /*2*/
    }
};

答案:

cpp
m.lock();
m.unlock();

解析:构造加锁,析构解锁,保证异常路径释放。

题目图示

F07. 代码填空

补全 unique_ptr 移交。

cpp
unique_ptr<int> a(new int(3));
unique_ptr<int> b = /*1*/;

答案:

cpp
std::move(a)

解析:unique_ptr 独占所有权,不可拷贝,只能移动。

题目图示

F11. 代码填空

补全 vector 删除遍历写法。

cpp
for (auto it=v.begin(); it!=v.end(); ) {
    if (*it%2==0) {
        it=/*1*/;
    }
    else {
        /*2*/;
    }
}

答案:

cpp
v.erase(it)
++it

解析:erase 返回删除后下一个有效迭代器。

题目图示

F12. 代码填空

补全移动构造清空源对象。

cpp
Buffer(Buffer&& o):p(o.p), n(o.n) {
    o.p=/*1*/;
    o.n=/*2*/;
}

答案:

cpp
nullptr
0

解析:接管资源后清空源对象,避免双重释放。

题目图示

F15. 代码填空

补全析构释放数组。

cpp
~Array() {
    delete /*1*/ data;
}

答案:

cpp
[]

解析:new[] 分配的数组必须用 delete[] 释放。

题目图示

读代码输出

O01. 读代码输出

构造析构顺序。

cpp
#include <iostream>
using namespace std;
struct A {
    A() {
        cout<<"A";
    }
    ~A() {
        cout<<"a";
    }
};
struct B {
    B() {
        cout<<"B";
    }
    ~B() {
        cout<<"b";
    }
};
int main() {
    A x;
    B y;
    cout<<"M";
}

输出:

text
ABMba

解析:局部对象按构造逆序析构。

题目图示

O02. 读代码输出

虚函数构造期调用。

cpp
#include <iostream>
using namespace std;
struct B {
    B() {
        f();
    }
    virtual void f() {
        cout<<"B";
    }
};
struct D:B {
    void f() override {
        cout<<"D";
    }
};
int main() {
    D d;
}

输出:

text
B

解析:基类构造期间虚调用不会分派到派生类。

题目图示

O03. 读代码输出

引用别名。

cpp
#include <iostream>
using namespace std;
int main() {
    int x=1;
    int& r=x;
    r=9;
    cout<<x;
}

输出:

text
9

解析:引用是别名,修改 r 就是修改 x。

题目图示

O04. 读代码输出

map operator[]。

cpp
#include <bits/stdc++.h>
using namespace std;
int main() {
    map<string, int> m;
    cout<<m["hp"]<<" "<<m.size();
}

输出:

text
0 1

解析:operator[] 访问不存在 key 会插入默认值。

题目图示

O05. 读代码输出

lambda 值捕获。

cpp
#include <iostream>
using namespace std;
int main() {
    int x=10;
    auto f=[x]() mutable {
        x+=2;
        return x;
    };
    cout<<f()<<" "<<x;
}

输出:

text
12 10

解析:mutable 修改的是捕获副本。

题目图示

O06. 读代码输出

sizeof 数组。

cpp
#include <iostream>
using namespace std;
int main() {
    int a[4]= {
    };
    cout<<sizeof(a)/sizeof(a[0]);
}

输出:

text
4

解析:数组当前作用域未退化,sizeof 得到总字节数。

题目图示

O07. 读代码输出

重载决议。

cpp
#include <iostream>
using namespace std;
void f(int) {
    cout<<"i";
}
void f(double) {
    cout<<"d";
}
int main() {
    f(1.0f);
}

输出:

text
d

解析:float 到 double 是提升,优于转 int。

题目图示

O08. 读代码输出

vector 迭代器陷阱。

cpp
#include <bits/stdc++.h>
using namespace std;
int main() {
    vector<int> v= {
        1, 2, 3
    };
    auto it=v.begin();
    v.push_back(4);
    cout<<*it;
}

输出:

text
未定义行为

解析:push_back 可能扩容导致 it 失效。

题目图示

O09. 读代码输出

static 局部变量。

cpp
#include <iostream>
using namespace std;
void f() {
    static int x=0;
    cout<<++x;
}
int main() {
    f();
    f();
    f();
}

输出:

text
123

解析:static 局部变量只初始化一次,值跨调用保留。

题目图示

O10. 读代码输出

前置后置自增。

cpp
#include <iostream>
using namespace std;
int main() {
    int x=1;
    cout<<x++<<" "<<++x;
}

输出:

text
1 3

解析:后置先返回旧值再加,前置先加再返回。

题目图示

O11. 读代码输出

多态删除缺虚析构。

cpp
#include <iostream>
using namespace std;
struct B {
    ~B() {
        cout<<"B";
    }
};
struct D:B {
    ~D() {
        cout<<"D";
    }
};
int main() {
    B* p=new D;
    delete p;
}

输出:

text
未定义行为/常见只输出B

解析:通过无虚析构的基类指针删除派生对象是未定义行为,不能把常见输出当标准答案。

题目图示

O12. 读代码输出

字符串长度。

cpp
#include <iostream>
#include <cstring>
using namespace std;
int main() {
    char s[]="abc";
    cout<<sizeof(s)<<" "<<strlen(s);
}

输出:

text
4 3

解析:字符数组含结尾 \0,strlen 不计 \0。

题目图示

O13. 读代码输出

指针算术。

cpp
#include <iostream>
using namespace std;
int main() {
    int a[]= {
        10, 20, 30
    };
    int* p=a;
    cout<<*(p+2);
}

输出:

text
30

解析:p+2 指向第三个元素。

题目图示

O14. 读代码输出

函数默认参数。

cpp
#include <iostream>
using namespace std;
void f(int a, int b=2) {
    cout<<a+b;
}
int main() {
    f(3);
}

输出:

text
5

解析:未传 b 时使用默认参数 2。

题目图示

O15. 读代码输出

短路求值。

cpp
#include <iostream>
using namespace std;
int main() {
    int x=0;
    if (x && ++x) {
    }
    cout<<x;
}

输出:

text
0

解析:&& 左侧为 false 时右侧不执行。

题目图示

O16. 读代码输出

shared_ptr 引用计数。

cpp
#include <iostream>
#include <memory>
using namespace std;
int main() {
    auto p=make_shared<int>(1);
    auto q=p;
    cout<<p.use_count();
}

输出:

text
2

解析:p 和 q 共享同一对象,引用计数为 2。

题目图示

O17. 读代码输出

虚函数动态绑定。

cpp
#include <iostream>
using namespace std;
struct B {
    virtual void f() {
        cout<<"B";
    }
};
struct D:B {
    void f() override {
        cout<<"D";
    }
};
int main() {
    D d;
    B& b=d;
    b.f();
}

输出:

text
D

解析:通过基类引用调用虚函数,动态绑定到 D::f。

题目图示

O18. 读代码输出

优先级。

cpp
#include <iostream>
using namespace std;
int main() {
    cout<<(1+2*3);
}

输出:

text
7

解析:乘法优先于加法。

题目图示

O19. 读代码输出

deque 简单操作。

cpp
#include <bits/stdc++.h>
using namespace std;
int main() {
    deque<int> q;
    q.push_back(1);
    q.push_front(2);
    cout<<q.front()<<q.back();
}

输出:

text
21

解析:push_front 放前面,push_back 放后面。

题目图示

O20. 读代码输出

set 去重排序。

cpp
#include <bits/stdc++.h>
using namespace std;
int main() {
    set<int> s= {
        3, 1, 3, 2
    };
    for (int x:s) {
        cout<<x;
    }
}

输出:

text
123

解析:set 去重并按 key 有序遍历。

题目图示

文章评价

读完这篇,留下你的看法

暂无审核通过的评价。

登录账号后才能评价。

本站访客数0总站访问量0本页访问量0