毫无疑问,我忽视了一些基本的东西,但我的实施显然存在缺陷。
我试图要求派生类来实现在基类中调用的方法。
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,所以我认为不在Clock
和Application
中定义纯虚方法,它需要Application
的所有衍生物定义OnTimeExpired()
方法。
我发现这将编译和链接(MSVS-2017),如果DerivedApp
未实现该方法,Clock
对象将调用未定义的方法并崩溃。
为什么在没有实现纯虚方法的情况下进行编译?
如何强制派生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()中删除注释,它将按照我希望的方式编译和运行。显然我的实际代码并没有像我想的那样遵循这个模型,所以现在我需要重新审视我出错的地方。感谢。
答案 0 :(得分:3)
C ++中没有强制类覆盖某些方法的关键字。但是,通过使OnTimeExpired()
纯虚拟,您可以使IClock
成为一个抽象类。从IClock
派生的任何未实现OnTimeExpired()
的类也将自动成为抽象类,因此不允许您创建这些类的对象。这意味着您的代码是完全合法的,除非您尝试制作这些类的对象
答案 1 :(得分: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;
}