gpt4 book ai didi

c++ - 在构造函数分配后更改 vtable 内存?

转载 作者:行者123 更新时间:2023-11-28 02:14:02 28 4
gpt4 key购买 nike

这是我在面试中被问到的问题......

Is it possible to change the vtable memory locations after it's 
created via constructor? If yes, is it a good idea? And how to do that?
If not, why not?

因为我对 C++ 没有那么深入的了解,所以我的猜测是,创建 vtable 之后是不可能更改它的!

谁能解释一下?

最佳答案

C++ 标准没有告诉我们必须如何实现动态调度。但 vtable 是最常见的方式。

一般来说,对象的前 8 个字节用于存储指向 vtable 的指针,但前提是对象至少有 1 个虚函数(否则我们可以将这 8 个字节留作其他用途)。并且在运行时不可能更改 vtable 中的记录。

但是你有 memset 或 memcpy 之类的函数,可以做任何你想做的事(改变 vtable 指针)。

代码示例:

#include <bits/stdc++.h>

class A {
public:
virtual void f() {
std::cout << "A::f()" << std::endl;
}
virtual void g() {
std::cout << "A::g()" << std::endl;
}
};

class B {
public:
virtual void f() {
std::cout << "B::f()" << std::endl;
}
virtual void g() {
std::cout << "B::g()" << std::endl;
}
};

int main() {
std::ios_base::sync_with_stdio(false);
std::cin.tie(nullptr);
A * p_a = new A();
B * p_b = new B();
p_a->f();
p_a->g();
p_b->f();
p_b->g();
size_t * vptr_a = reinterpret_cast<size_t *>(p_a);
size_t * vptr_b = reinterpret_cast<size_t *>(p_b);
std::swap(*vptr_a, *vptr_b);
p_a->f();
p_a->g();
p_b->f();
p_b->g();
return 0;
}

输出:

A::f()
A::g()
B::f()
B::g()
B::f()
B::g()
A::f()
A::g()

https://ideone.com/CEkkmN

当然,所有这些操作都是搬起石头砸自己的脚。

关于c++ - 在构造函数分配后更改 vtable 内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34618957/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com