首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >多个vtable,呼叫时出现错误vtable

多个vtable,呼叫时出现错误vtable
EN

Stack Overflow用户
提问于 2017-11-02 02:05:01
回答 1查看 219关注 0票数 0

我有以下设置:

代码语言:javascript
复制
class CRpCat : 
    public CQueryDataBase,
    public IRpCat 
    {
public:
    CRpCat();
    virtual ~CRpCat();

// IRpCat
public:
    virtual HRESULT Initialize();

.诸如此类......

代码语言:javascript
复制
class CQueryDataBase : public CQueryNotify
{
    // this has virtual functions, all concrete
    virtual void OnDataChange(ULONG nRow, DBREASON eReason);

.诸如此类......

代码语言:javascript
复制
class CQueryNotify 
{
public:
    // abstract signatures
    virtual void OnDataChange(ULONG nRow, DBREASON eReason) = 0;

.废话......

最后

代码语言:javascript
复制
class IRpCat
{
public:
    virtual HRESULT Initialize() = 0;

所以,我有一个从两个类派生的类,到处都是虚函数。派生的类不在一个父类下--这不是菱形问题(尽管可能与之相关)

这是问题所在。在实例化该类并进行Initialize()调用时,我在OnDataChange()中结束:

代码语言:javascript
复制
IRpCat *pCat = GetInstance()->GetRpCat();
pCat->Initialize();

Initialize()和OnDataChange()都是它们各自的vtable插槽中的第一个函数--所以我不知道是怎么回事,但我知道Initialize()调用是通过vtable进行的--但不幸的是,我最终进入了错误的vtable。凭直觉,我尝试了以下几种方法:

通过将第一行设为虚的,我在Initialize()中结束了,正确地()

代码语言:javascript
复制
class CRpCat : 
       public virtual CQueryDataBase,
       public IRpCat 
       {

通过将第二行设为虚拟的,我错误地以OnDataChange()结束。

代码语言:javascript
复制
class CRpCat : 
       public CQueryDataBase,
       public virtual IRpCat 
       {

通过使这两行代码都是虚的,它会在进行Initialize()调用时抛出异常

代码语言:javascript
复制
class CRpCat : 
       public virtual CQueryDataBase,
       public virtual IRpCat 
       {

那么,有人能解释一下到底是怎么回事吗?(顺便说一下,这是Visual Studio C++ )。这肯定与vtable的布局方式有关。谢谢

EN

回答 1

Stack Overflow用户

发布于 2017-11-02 03:54:29

我想通了。问题在于实例化对象的方式:

代码语言:javascript
复制
void * p = new CRpCat();
IRpCat * p2 = static_cast<IRpCat *>(p);
p2->Initialize();

首先将指针存储在"void *“中,然后对其进行强制转换,这就是对指针进行”切片“--因此产生了奇怪的结果。谢谢你们所有人。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47061060

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档