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()
方法
#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;
}