为什么我的虚函数调用会失败?

Nic*_*ton 1 c++ virtual-functions

更新:此问题是由内存使用不良引起的,请参阅底部的解决方案.

这是一些半伪代码:

class ClassA
{
public:
    virtual void VirtualFunction();
    void SomeFunction();
}

class ClassB : public ClassA
{
public:
    void VirtualFunction();
}

void ClassA::VirtualFunction()
{
    // Intentionally empty (code smell?).
}

void ClassA::SomeFunction()
{
    VirtualFunction();
}

void ClassB::VirtualFunction()
{
    // I'd like this to be called from ClassA::SomeFunction()
    std::cout << "Hello world!" << endl;
}
Run Code Online (Sandbox Code Playgroud)

C#等价物如下:删除了C#示例,因为它与实际问题无关.

ClassB::VirtualFunction调用函数时为什么不调用函数ClassA::SomeFunction?相反ClassA::VirtualFunction被称为......

当我强制实现虚函数 ClassA :: VirtualFunction时,如下所示:

class ClassA
{
public:
    virtual void VirtualFunction() = 0;
    void SomeFunction();
}

class ClassB : public ClassA
{
public:
    void VirtualFunction();
}

void ClassA::SomeFunction()
{
    VirtualFunction();
}

void ClassB::VirtualFunction()
{
    // I'd like this to be called from ClassA::SomeFunction()
    std::cout << "Hello world!" << endl;
}
Run Code Online (Sandbox Code Playgroud)

尽管在deffinately声明和定义了derrived函数,但在运行时会发生以下错误.

pure virtual method called
terminate called without an active exception
Run Code Online (Sandbox Code Playgroud)

注意:即使内存使用不良,似乎也可能导致错误.有关详细信息,请参阅自我答案

更新1 - 4:

评论已删除(不是重新发布).

解:

张贴作为答案.

Dav*_*eas 5

class Base {
public:
   virtual void f() { std::cout << "Base" << std::endl; }
   void call() { f(); }
};
class Derived : public Base {
public:
   virtual void f() { std::cout << "Derived" << std::endl; }
};
int main()
{
   Derived d;
   Base& b = d;
   b.call(); // prints Derived
}
Run Code Online (Sandbox Code Playgroud)

如果在Base类中你不想实现该函数,则必须声明:

class Base {
public:
   virtual void f() = 0; // pure virtual method
   void call() { f(); }
};
Run Code Online (Sandbox Code Playgroud)

并且编译器不允许您实例化该类:

int main() {
   //Base b; // error b has a pure virtual method
   Derived d; // derive provides the implementation: ok
   Base & b=d; // ok, the object is Derived, the reference is Base
   b.call();
}
Run Code Online (Sandbox Code Playgroud)

作为旁注,请注意不要从构造函数或析构函数中调用虚函数,因为您可能会得到意外的结果.