非常に奇妙な振る舞いをするコードを作成しています。仮想継承のない奇妙な振る舞い
#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
が2回呼び出されます。
この動作の原因は何ですか? virtual
継承を使用せずに正しい動作を再現するためにコードを再因子化するにはどうすればよいですか?
どのコンパイラを使用しましたか?とにかく 'g ++ .exe(Rev1、MSYS2プロジェクトで構築されたRev1)7.2.0' –
' -std = C++ 11'でコンパイルされた@underscore_d 'g ++ 5.4.0' – Nick
私は' C++ 11'(コードを少し変更したもの)。 – Nick