gpt4 book ai didi

c++ - 是否有可能在构造函数和析构函数之外修改 `vptr`?

转载 作者:行者123 更新时间:2023-11-30 01:57:02 25 4
gpt4 key购买 nike

我正在阅读 Inside C++ Object Model 一书中与对象破坏相关的主题并遇到了这个问题。

它表示在执行用户自定义析构函数之前,析构函数将被扩充。扩充的第一步是将 vptr 指针重置为该类的虚函数表。我记得相应地,就在构造函数中执行用户代码(阻塞构造函数体中的语句)之前,vptr 已经正确设置,以防在构造过程中调用虚拟成员函数。

问题是析构函数扩充中的重置 vptr 步骤是否是必须的。如果是这样,则对象中的 vptr 一定有可能在某处更新。这可能在什么时候发生?

最佳答案

它可能发生在派生类的析构函数中。假设你有:

class Foo : public Bar : public Baz

现在,假设您有一个 Foo .在 Foo::~Foo , 这是一个 Foo ,这就是它必须使用的虚函数表。但是当Foo::~Foo完成,它不是 Foo了。这是一个Bar ,这就是它必须使用的虚函数表。当Bar::~Bar完成,它只是一个Baz , 所以在 Baz::~Baz , 它必须使用 Baz 的虚函数表.

指向虚函数表的指针不会改变,除非在构造函数和析构函数中。

下面是一些示例代码:

    #include <string>  
#include <iostream>

class Foo
{
public:
Foo() { print("Foo::Foo"); }
virtual ~Foo() { print("Foo::~Foo"); }
virtual void print(std::string j) { std::cout << j << "(Foo)" << std::endl; }
};

class Bar : public Foo
{
public:
Bar() { print("Bar::Bar"); }
virtual ~Bar() { print("Bar::~Bar"); }
virtual void print(std::string j) { std::cout << j << "(Bar)" << std::endl; }
};

class Baz : public Bar
{
public:
Baz() { print("Baz:Baz"); }
virtual ~Baz() { print("Baz::~Baz"); }
virtual void print(std::string j) { std::cout << j << "(Baz)" << std::endl; }
};

int main(void)
{
std::cout << "Constructing Baz" << std::endl;
{
Baz j;
std::cout << "Baz constructed" << std::endl;
}
std::cout << "Baz destructed" << std::endl;
}

输出是:

Constructing Baz
Foo::Foo(Foo)
Bar::Bar(Bar)
Baz:Baz(Baz)
Baz constructed
Baz::~Baz(Baz)
Bar::~Bar(Bar)
Foo::~Foo(Foo)
Baz destructed

你可以看到 Foo构建然后用于制作Bar用于制作最终的 Baz .在销毁时,~Baz把它变成 Bar然后 ~Bar把它变成 Foo . ~Foo做最后的破坏。

关于c++ - 是否有可能在构造函数和析构函数之外修改 `vptr`?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19205641/

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