多个vtable,在打电话时出现错误
multiple vtables, ending up in the wrong one when making a call
我有以下设置:
class CRpCat :
public CQueryDataBase,
public IRpCat
{
public:
CRpCat();
virtual ~CRpCat();
// IRpCat
public:
virtual HRESULT Initialize();
等等。。。。。。。
class CQueryDataBase : public CQueryNotify
{
// this has virtual functions, all concrete
virtual void OnDataChange(ULONG nRow, DBREASON eReason);
等等。。。。。。。
class CQueryNotify
{
public:
// abstract signatures
virtual void OnDataChange(ULONG nRow, DBREASON eReason) = 0;
等等。。。。。。。。。。。。。。
最后是
class IRpCat
{
public:
virtual HRESULT Initialize() = 0;
所以,我有一个派生自两个类的类,到处都是虚拟函数。派生自的类不在一个父类下——这不是钻石问题(尽管可能与其相关)
问题来了。当实例化类并调用Initialize()时,我最终会使用OnDataChange():
IRpCat *pCat = GetInstance()->GetRpCat();
pCat->Initialize();
Initialize()和OnDataChange()都是各自vtable槽中的第一个函数——所以我不明白发生了什么,但我知道Initialize(。凭直觉,我尝试了以下方法:
通过使第一行成为虚拟行,我最终正确地进入Initialize()
class CRpCat :
public virtual CQueryDataBase,
public IRpCat
{
通过将第二行设为虚拟行,我错误地进入了OnDataChange()
class CRpCat :
public CQueryDataBase,
public virtual IRpCat
{
通过使这两行都是虚拟的,它在Initialize()调用时抛出异常
class CRpCat :
public virtual CQueryDataBase,
public virtual IRpCat
{
那么,有人能解释一下发生了什么吗?(顺便说一下,这是Visual Studio C++)。这肯定与vtables的布局方式有关。谢谢
想明白了。问题在于对象的实例化方式:
void * p = new CRpCat();
IRpCat * p2 = static_cast<IRpCat *>(p);
p2->Initialize();
先将指针存储在"void*"中,然后进行强制转换,这是对指针的"切片"——因此会产生奇怪的结果。谢谢大家。
相关文章:
- 警告处理为错误这里有什么问题
- "error: no matching function for call to"构造函数错误
- boost::进程间消息队列引发错误
- C++,OpenCV,尝试显示图像时"OpenCV(4.3.0) Error: Assertion failed (size.width>0 && size.height>0)"此错误
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- QT在错误的班级中寻找空位
- vector.resize()中的分配错误
- 代码在main()中运行,但在函数中出现错误
- 释放错误后堆使用
- (C++)分析树以计算返回错误值的简单算术表达式
- Project Euler问题4的错误解决方案
- 我的字符计数代码计算错误.为什么
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 尝试导入pybind-opencv模块时出现libgtk错误
- CMake项目Boost库错误:Boost/config/compiler/gcc.hpp:165:10:致命错误:cs
- 在某些循环内使用vector.push_back时出现分段错误
- MSVC多行宏编译器错误
- 静态数据成员的问题-修复链接错误会导致编译器错误
- 打电话时返回未知错误
- 多个vtable,在打电话时出现错误