gpt4 book ai didi

c++ - 没有虚拟继承的奇怪行为

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:50:28 25 4
gpt4 key购买 nike

<分区>

我正在处理一段表现出非常奇怪行为的代码。我设法在一个简单的 hello world 风格的程序中复制了它,代码如下:

#include <iostream>
using namespace std;

class Test
{
public:
virtual ~Test() = default;

protected:
virtual void SetUp() { }
};

class ICallbackReceiver
{
public:
virtual ~ICallbackReceiver() = default;
virtual void onReady() = 0;
};

// C-style callback
void readyReceiver(void* userdata)
{
cout << "3) readyReceiver\n";
static_cast<ICallbackReceiver*>(userdata)->onReady();
}

using callback_t = void(*)(void*);
callback_t myCallback;
void* myUserData;

void registerCallback(callback_t callback, void* userData)
{
cout << "2) registerCallback\n";
myCallback = callback;
myUserData = userData;
}

class ConfigurableTest : public /*virtual*/ Test, public ICallbackReceiver
{
public:

void SetUp() override
{
cout << "1) ConfigurableTest::SetUp\n";
registerCallback(&readyReceiver, static_cast<void*>(this));
}

void onReady() override
{
cout << "4) ConfigurableTest::onReady\n";
}
};

int main()
{
ConfigurableTest test;
test.SetUp();

myCallback(myUserData);

return 0;
}

每当 myCallback 被调用时,就必须测试一些东西。这是应该显示的输出:

1) ConfigurableTest::SetUp
2) registerCallback
3) readyReceiver
4) ConfigurableTest::onReady

但是,除非我为 Test 类指定一个 virtual 继承,否则这是我看到的输出:

1) ConfigurableTest::SetUp
2) registerCallback
3) readyReceiver
1) ConfigurableTest::SetUp
2) registerCallback

如您所见,ConfigurableTest::onReady 从未被调用,但 ConfigurableTest::SetUp 实际上被调用了两次!

这种行为的起源是什么?如何在不使用 virtual 继承的情况下重构代码以重现正确的行为?

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