需要派生类来定义方法

问题描述 投票:-2回答:2

毫无疑问,我忽视了一些基本的东西,但我的实施显然存在缺陷。

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

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() { ... }
}

我很少使用纯ABCs,所以我认为不在ClockApplication中定义纯虚方法,它需要Application的所有衍生物来定义OnTimeExpired()方法。

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

  1. 为什么在没有实现纯虚方法的情况下进行编译?
  2. 如何强制派生的Application类来实现OnTimeExpired()方法?

编辑:崩溃是由于无关的错误 - 我道歉。不过我提出的问题仍然适用。

这里要求的是一个完整的,可构建的,最小的例子:

IClock.h:

#pragma once

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

Clock.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;
//}

main.cpp中

#include "DerivedApp.h"

class App : public DerivedApp
{
public:
    App(){}
    ~App(){}
};

int wmain(int argc, wchar_t * argv[])
{
    App *app = new App();
    app->Init();
    app->Run();
    delete app;
}

感谢那些要求最小化工作示例的人,我构建了它并且它完全按照我的希望工作。编译器会抱怨App类中没有ABC的实例化。如果我从DerivedApp :: OnClockTime()中删除注释,它将按照我希望的方式编译和运行。显然我的实际代码并没有像我想的那样遵循这个模型,所以现在我需要重新审视我出错的地方。谢谢。

c++ c++11 abstract-class
2个回答
3
投票

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


0
投票
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;
}
© www.soinside.com 2019 - 2024. All rights reserved.