基构造函数中的 C++/CX 委托失败,并出现纯虚拟调用断言

C++/CX Delegate in base constructor fails with pure virtual call assertion

本文关键字:断言 调用 虚拟 失败 构造函数 C++ CX      更新时间:2023-10-16

我不明白为什么以下代码失败并调用 purvirt 调用并调用abort();

这是一个使用 C++/CX 的 WinRT 项目

namespace Test {
    public delegate void TickHandle();
    ref class Clock {
    public:
        event TickHandle^ Tick;
    };

    ref class Base {
    internal:
        Base() :
            m_clock(ref new Clock())
        {
            std::cout << "Base::Base" << std::endl;
            m_clock->Tick += ref new Test::TickHandle(this, &Test::Base::OnTick);
            OnTick();
        }
    protected:
        virtual void Foo() = 0;
    private:
        Clock^ m_clock;
        void OnTick()
        {
            std::cout << "Tick" << std::endl;
        }
    };
    ref class Derive : public Base{
    internal:
        Derive() 
        {
            std::cout << "Derive::Derive" << std::endl;
        }
    protected:
        void Foo() override
        {
            std::cout << "Derive::Foo" << std::endl;
        }
    };
    void main()
    {
        auto y = ref new Test::Derive();
    }
}

注册到Tick事件是故障线,由于某种原因,它被认为是对我不知道什么的纯虚拟调用。

我尝试了这个例子,并注意到了一些事情:

  1. 仅当基类是纯虚拟类时,才会发生这种情况(请注意 Foo() = 0 (

  2. Base::Tick是私有\公共\受保护并不重要等。。。

  3. 我可以(显然(从构造函数调用OnTick() Base并且可以工作

有人得到解释吗?

C++/CX 只是一个编译器包装器,用于简化 COM 对象。这意味着实现 IUnknown 的对象。在 Base 的构造函数中,IUnknown的虚函数表尚未初始化,因此所有条目都是"纯虚拟"。当您尝试注册 tick 处理程序时,它希望通过调用 IUnknown::AddRef 来添加对 this 的引用,在对象完全构造之前,该引用仍指向"纯虚拟"实现。