C++ 要求派生类定义方法

C++ 要求派生类定义方法,c++,c++11,abstract-class,C++,C++11,Abstract Class,毫无疑问,我忽略了一些基本的东西,但我的实现显然有缺陷 我试图要求派生类实现在基类中调用的方法 class IClock { public: virtual void OnTimeExpired() = 0; } class Clock : public IClock { ... // ABC not implemented } class Application : public Clock { ... // ABC not implemented } class

毫无疑问,我忽略了一些基本的东西,但我的实现显然有缺陷

我试图要求派生类实现在基类中调用的方法

class IClock
{
public:
    virtual void OnTimeExpired() = 0;
}

class Clock : public IClock
{
    ... // ABC not implemented
}

class Application : public Clock
{
    ... // ABC not implemented
}

class DerivedApp : public Application
{
public: 
    virtual void OnTimeExpired() { ... }
}
我很少使用纯ABC,因此我认为通过而不是
Clock
Application
中定义纯虚拟方法,将需要
Application
的所有衍生工具来定义
OnTimeExpired()
方法

我发现这将编译并链接(MSVS-2017),如果
DerivedApp
没有实现该方法,则
Clock
对象将调用未定义的方法并崩溃。

  • 为什么在没有实现纯虚拟方法的情况下进行编译

  • 如何强制派生的
    应用程序
    类实现
    OnTimeExpired()
    方法

  • 编辑:崩溃是由于不相关的错误造成的-我道歉。尽管如此,我提出的问题仍然适用。

    根据要求,这里有一个完整的、可构建的、最少的示例:

    IClock.h:

    #pragma once
    
    class IClock
    {
    public:
        virtual void OnClockTime() = 0;
    };
    
    时钟h:

    #pragma once
    #include "IClock.h"
    
    class Clock : public IClock
    {
    public:
        Clock();
        virtual ~Clock();
        void ClockUpdate();
        virtual void OnClockTime();
    
    private:
        float elapsed_time;
    };
    
    Clock.cpp:

    #include "Clock.h"
    
    Clock::Clock()
        : elapsed_time(0.0f)
    {
    }
    
    Clock::~Clock()
    {
    }
    
    void Clock::ClockUpdate()
    {
        elapsed_time += 0.0000001f; // small ticks for testing
        if (elapsed_time >= 1.0f) {
            OnClockTime();
            elapsed_time -= 1.0f;
        }
    }
    void Clock::OnClockTime()
    {}
    
    ApplicationBase.h

    #pragma once
    #include "Clock.h"
    
    class ApplicationBase : public Clock
    {
    public:
        ApplicationBase();
        virtual ~ApplicationBase();
    
        virtual void Init(){}
        virtual void Run(){}
    
    protected:
        bool app_run;
    };
    
    ApplicationBase.cpp:

    #include "ApplicationBase.h"
    
    ApplicationBase::ApplicationBase()
        : app_run(false)
    {
    }
    
    ApplicationBase::~ApplicationBase()
    {
    }
    
    DerivedApp.h:

    #pragma once
    #include "ApplicationBase.h"
    
    class DerivedApp : public ApplicationBase
    {
    public:
        DerivedApp();
        virtual ~DerivedApp();
    
        virtual void Init() {}
        virtual void Run();
    
        //virtual void OnClockTime();
    };
    
    DerivedApp.cpp:

    #include "DerivedApp.h"
    #include <iostream>
    
    DerivedApp::DerivedApp()
    {
    }
    
    DerivedApp::~DerivedApp()
    {
    }
    
    void DerivedApp::Run()
    {
        app_run = true;
        while (app_run) {
            ClockUpdate();
        }
    }
    
    //void DerivedApp::OnClockTime()
    //{
    //  static int counts(0);
    //  std::cout << "Tick..." << std::endl;
    //  counts++;
    //  if (counts >= 10)
    //      app_run = false;
    //}
    

    多亏了那些要求提供最小工作示例的人,我构建了它,它完全按照我所希望的那样工作。编译器将抱怨应用程序类中没有ABC的实例化。如果我从DerivedApp::OnClockTime()中删除注释,它将按照我希望的方式编译和运行。很明显,我的实际代码并没有像我想的那样遵循这个模型,所以现在我需要重新检查哪里出了问题。谢谢。

    C++中没有关键字强制一个类重写某些方法。然而,通过使
    OnTimeExpired()
    纯虚拟,您正在使
    IClock
    成为一个抽象类。任何从
    IClock
    派生的类,如果没有实现
    OnTimeExpired()
    ,也将自动成为抽象类,因此不允许您创建这些类的对象。这意味着您的代码是完全合法的,除非您尝试创建这些类的对象

    class AbstractBase {
    public:
        virtual void someFunc() = 0; // Purely Virtual
    };
    
    class AbstractDerived : public AbstractBase {
    public:
        void someOtherFunc();
    
        // Still abstract because the following is not declared-defined
        // void someFunc() override { ... }
    };
    
    class NonAbstractDerivedA : public AbstractBase { // Derived From Base
    public:
        void someFunc() override { /* do this class's implementation*/ }
    };
    
    class NonAbstractDerivedB : public AbstractDerived { // Derived From AbstractDerived
    public: 
        void someFunc() override { /* do this class's implementation*/ }
    };
    
    用途:


    请您尝试创建一个编译但随后崩溃的程序,并将其显示给我们好吗?您显示的代码确实定义了
    OnTimeExpired
    。但是,它不调用该方法。你有编译或崩溃的最小例子吗?你曾经尝试直接实例化<代码>应用程序< /Cord>对象吗?“C++中没有关键字强制一个类重写某些方法”不是一个特定的关键字,不是,而是一个纯的虚拟方法完成了同样的事情,编译器应该无法实例化任何具有未被重写的纯方法的类。
    class AbstractBase {
    public:
        virtual void someFunc() = 0; // Purely Virtual
    };
    
    class AbstractDerived : public AbstractBase {
    public:
        void someOtherFunc();
    
        // Still abstract because the following is not declared-defined
        // void someFunc() override { ... }
    };
    
    class NonAbstractDerivedA : public AbstractBase { // Derived From Base
    public:
        void someFunc() override { /* do this class's implementation*/ }
    };
    
    class NonAbstractDerivedB : public AbstractDerived { // Derived From AbstractDerived
    public: 
        void someFunc() override { /* do this class's implementation*/ }
    };
    
    #include "above"
    
    int main() {
        AbstractBase base; // compiler error
    
        AbstractDerived derived; // compiler error
    
        NonAbstractDerivedA derivedA; // should be okay
    
        NonAbstractDerivedB derivedB; // should be okay
    
        return 0;
    }