可以在下面的代码看,我有一个抽象基类“HostWindow”,和从它“铬”派生类。所有的功能都在Chrome中实现的。问题是,如果他们是虚拟的,我不能调用函数在Chrome。

class HostWindow : public Noncopyable {
public:
    virtual ~HostWindow() { }

    // Pure virtual functions:
    virtual void repaint(const IntRect&, bool contentChanged, bool immediate = false, bool repaintContentOnly = false) = 0;
    virtual void scrollbarsModeDidChange() const = 0;
}

class Chrome : public HostWindow {
    // HostWindow functions:
    virtual void repaint(const IntRect&, bool contentChanged, bool immediate = false, bool repaintContentOnly = false);
    virtual void scrollbarsModeDidChange() const;

    void focus() const;
}

因此,可以说,我们有镀铬的一个实例,我们所说的几个功能:

WebCore::Chrome *chrome = new Chrome();
chrome->repaint(IntRect(), true); // Null pointer error
chrome->focus(); // returns void (works)

在空指针错误我得到每当我调用虚函数是:

  

方案接收信号EXC_BAD_ACCESS,无法访问存储器。   原因是:在KERN_PROTECTION_FAILURE地址:0x00000008

任何想法是怎么回事?

<强>更新 正如你们许多人指出的 - 这个代码实际运行。不幸的是,我不能提供一个更加充满例子,因为代码是内部的WebCore(WebKit的)深。不过,我已经收窄的问题。如果我手动创建一个Chrome的实例,调用虚函数工作。所以,问题是与这个特殊的镀铬实例 - 它不能正确实例化。现在,Chrome浏览器实例在另一个类的构造函数实例。我会进一步调查......

<强>更新2: 好了,检查有冲突的情况下的虚函数表显示,这是空;从GDB:

p *(void **)chrome
$52 = (void *) 0x0

一个正常的实例有一个正确的虚表。所以,我得工作了,为什么虚函数表是零 - 我不知道怎么会发生呢?也许是因为它被实例化在一些其他类的构造函数?

<强>更新3: 貌似我对这个问题是它的内部另一个类的构造函数实例化正确的。

所以,在实例化是这样的:

Page::Page(ChromeClient* chromeClient, ...)
    : m_chrome(new Chrome(this, chromeClient))

和m_chrome是无效的情况下,用零虚表。 我已经改变的实例化,以便它发生时第一次需要的变量(在此包括保存ChromeClient购买):

Page::Page(ChromeClient* chromeClient, ...)
    : m_chrome(0)
    , m_chrome_client(chromeClient)

Chrome* Page::chrome() const {
  if(!m_chrome) {
    m_chrome = new Chrome(this, m_chrome_client);
  }
  return m_chrome;
}

现在的页::铬()情况下是正确的,用适当的虚函数表 - 而奇

<强>更新4: 最近更新的,我保证:)。好了,我已经确切地精确定位下来。你得到正确的实例,用虚函数表,如果你在页面构造的身体实例化。如果您在页面构造的头部实例,它没有一个虚函数表。是否有在类型变量的设置,您可以在构造函数中的头做任何限制吗?我想这是另一个问题#1

由于球员被如此有益的。

有帮助吗?

解决方案

是,则“这个”指针是零。加8获得的偏移,并且有是你的错。你显然不具有任何实际的对象都没有。

由于您没有足够的发布代码,真正交手,我猜。无论是整个这个指针为0,或虚函数表指针为0,也许是因为它被创建后该对象已被删除,您尝试调用它。

我可以给你最好的建议是建立一个更小的试管中。要么你会发现你的问题,或者你会最终有一个可发布的例子。

在VTBL不到位在一个实例直到施工过程的结束。事实上,该规范要求VTBL的渐进修改以匹配结构的类层次结构的状态。

其他提示

你能发布完整的代码?

在代码轻微的修改(无论是可用的),它的工作原理后:

#include <iostream>

class HostWindow  {
public:
    virtual ~HostWindow() { }

    // Pure virtual functions:
    virtual void repaint(const int , bool contentChanged, bool immediate = false, bool repaintContentOnly = false) = 0;
    virtual void scrollbarsModeDidChange() const = 0;
};

class Chrome : public HostWindow {
public:
    // HostWindow functions:
    virtual void repaint(const int , bool contentChanged, bool immediate = false, bool repaintContentOnly = false) 
    {
        std::cout << "In repaint." << std::endl;
    }
    virtual void scrollbarsModeDidChange() const { }

    void focus() const
    {
        std::cout << "In focus." << std::endl;
    }
};

int main()
{
    Chrome *chrome = new Chrome();
    chrome->repaint(1, true); // Null pointer error
    chrome->focus();
    delete chrome;
    return 0;
}

我不熟悉你的代码基础,但你不应该写:

// note the 'WebCore::Chrome()'
WebCore::Chrome *chrome = new WebCore::Chrome();
chrome->repaint(IntRect(), true); // 'chrome' should be a valid pointer now

,而不是:

WebCore::Chrome *chrome = new Chrome();
chrome->repaint(IntRect(), true); // Null pointer error

ssume您的不可复制表现如下(至少对于矿一样)

class NonCopyable
{
protected:
    NonCopyable() {}
    ~NonCopyable() {}
private:
    NonCopyable( const NonCopyable& );
    const NonCopyable& operator=( const NonCopyable& );
};

在插入后的公共的修改,以一流的Chrome的功能,并为他们的一些虚拟实现,整个事情的工作没有规定的问题。

  
    
      

有与发布的代码没有问题,它可能是你正在做的事情错了,这里没有张贴这些部分。

    
  

最后,DO检查分配失败。 (是的, “新” 是在堆分配)

我发现,这正在通过允许导出的全部符号引起的。

通常,WebCore的只有导出的符号的一个子集 - 基本上对事物WebKit所需要

我改变了每个码元导出 - 和它在某种程度上导致该错误

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top