腾讯互娱 C++开发 一面

1. cpp 的虚函数和纯虚函数

答案:虚函数是为了支持运行时多态。父类把成员函数声明为 virtual 之后,子类可以重写它,通过父类指针或引用调用时,会根据对象的真实类型决定执行哪个版本。纯虚函数是在虚函数声明后写上 = 0,表示这个函数只定义接口、不提供默认实现。只要类里存在纯虚函数,这个类通常就是抽象类,不能直接实例化,派生类如果不实现这些纯虚函数,也不能实例化。虚函数强调“可以重写”,纯虚函数强调“必须实现”。工程里纯虚函数经常用于定义接口层,比如网络连接接口、日志接口、存储接口。

代码:

#include <iostream>
using namespace std;

class Base {
public:
    virtual void f() { cout << "Base::f\n"; }
    virtual void g() = 0;
    virtual ~Base() = default;
};

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

int main() {
    Base* p = new Derived();
    p->f();
    p->g();
    delete p;
    return 0;
}

2. 虚函数的底层是怎么实现的

答案:主流编译器一般通过虚函数表实现多态。如果一个类里有虚函数,那么对象内部通常会有一个隐藏的虚表指针,指向该类对应的虚函数表。虚函数表里存的是虚函数入口地址。当通过基类指针调用虚函数时,程序不是直接静态绑定到某个函数,而是先找到对象中的虚表指针,再去虚表里查实际要调用的函数地址。所以虚函数调用比普通函数多了一次间接寻址,但换来了运行时的动态分派能力。多继承、虚继承场景下,对象布局和 this 指针调整会更复杂。

3. 说一下 C++ 里对象内存布局和内存对齐

答案:一个普通 C++ 对象通常包含它的非静态成员变量,如果类里有虚函数,还会额外有一个虚表指针。静态成员变量不放在对象实例里。内存对齐是为了让 CPU 更高效地访问数据,也为了满足硬件对某些类型访问边界的要求。编译器会根据成员类型的对齐要求插入 padding,所以类大小往往不是成员大小简单相加。这也是为什么调换成员顺序可能会影响 sizeof 结果。工程里如果对象数量很多,合理调整成员顺序能减少内存浪费。

代码:

#include <iostream>
using namespace std;

class A {
public:
    virtual void f() {}
    char c;
    int x;
    short y;
};

int main() {
    cout << sizeof(A) << endl;
    return 0;
}

4. defer 的执行顺序是什么样的

答案:多个 defer 会按照后进先出的顺序执行,也就是栈结构。谁最后被 defer 注册,谁最先执行。这个设计很适合做成对资源的释放,比如先加锁后解锁、先打开文件后关闭文件,执行顺序正好和申请顺序相反。另外要注意,defer 注册时会先计算参数,再延迟执行函数体。这个细节经常被拿来考。

代码:

package main

import "fmt"

func main() {
    defer fmt.Println(1)
    defer fmt.Println(2)
    defer fmt.Println(3)
}

5 在 for 循环里执行 defer 的结果是什么样的

答案:如果在 for 循环中不断写 defer,这些延迟调用不会在每轮循环结束时执行,而是会等整个函数返回时统一触发,并且仍然遵循后进先出。所以如果循环很多次,defer 会不断堆积,既影响执行顺序,也可能带来额外内存开销。这题常见陷阱还有循环变量捕获问题。如果闭包里直接引用循环变量,最终看到的值往往不是你直觉里每轮各自独立的那个值。

代码:

package main

import "fmt"

func main() {
    for i := 0; i < 3; i++ {
        defer fmt.Println(i)
    }
}

6. 想在每个循环结束后执行 defer 应该怎么做

答案:因为 defer的作用域是函数,不是循环体,所以如果想在每轮循环结束时就执行收尾动作,通常做法是把这一轮逻辑包装进一个匿名函数或者普通函数里

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

C++ 常考面试题总结 文章被收录于专栏

本专栏系统梳理C++方向, 大中厂高频高频面试考点 , 内容皆来自真实面试经历,从基础语法、内存管理、STL与设计模式,到操作系统与项目实战,结合真实面试题深度解析,帮助开发者高效查漏补缺,提升技术理解与面试通过率,打造扎实的C++工程能力.

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务