提问人:Rodo 提问时间:7/1/2023 最后编辑:Remy LebeauRodo 更新时间:7/1/2023 访问量:95
虚函数的这两个定义之间有什么区别?[复制]
What's the difference between these two definitions of a virtual function? [duplicate]
问:
我在一个名为TouchGFX的东西中遇到了一个错误,有人向我指出,类中的虚拟函数需要用大括号来定义,而不是在其名称末尾使用分号。我可以做基本的 C++,但继承、虚函数等不是我经常使用的东西。
#1 和 #2 定义虚拟函数 setTimeDate()
的方式有什么区别?
TouchGFX允许您为显示器创建“屏幕”。就像你的手机显示屏一样。打开它,有一个屏幕。如果您滑动或打开应用程序,则会看到不同的屏幕。
有两个类适用于所有屏幕(和)。项目中的每个屏幕都增加了两个类(和一个)。我在下面展示了类,但还有另一个......中没有定义虚函数...我还没有了解代码的那部分。我得到的错误是:model
modelListener
Presenter
View
principalScreen
SecondScreen
SecondScreen
./Application/User/gui/SecondScreenPresenter.o:(.rodata._ZTV21SecondScreenPresenter+0x28):undefined reference to `ModelListener::setTime(displayTime_t)'
osMessageQueueGetCount, osMessageQueueGet are part of [CMSIS-RTOS2](https://www.keil.com/pack/doc/CMSIS/RTOS2/html/group__CMSIS__RTOS__Message.html).
我只更改了类中的定义,错误就消失了。model
virtual void setTime(displayTime_t time); // #1 error
virtual void setTime(displayTime_t time){} // #2 correct
class ModelListener
{
public:
ModelListener() : model(0) {}
virtual ~ModelListener() {}
void bind(Model* m)
{
model = m;
}
virtual void setTimeDate(displayTimeDate_t nTimeDate){}
protected:
Model* model;
};
Model::Model() : modelListener(0), newTimeDate({0})
{
}
void Model::tick()
{
if(osMessageQueueGetCount(qRTCtoUIHandle)>0)
{
if(osMessageQueueGet(qRTCtoUIHandle, &newTimeDate, 0, 0)==osOK)
{
modelListener->setTimeDate(newTimeDate);
}
}
}
class principalScreenPresenter : public touchgfx::Presenter, public ModelListener
{
public:
principalScreenPresenter(principalScreenView& v);
/**
* The activate function is called automatically when this screen is "switched in"
* (ie. made active). Initialization logic can be placed here.
*/
virtual void activate();
/**
* The deactivate function is called automatically when this screen is "switched out"
* (ie. made inactive). Teardown functionality can be placed here.
*/
virtual void deactivate();
virtual ~principalScreenPresenter() {};
virtual void setTimeDate(displayTimeDate_t nTimeDate);
private:
principalScreenPresenter();
principalScreenView& view;
};
class principalScreenView : public principalScreenViewBase
{
public:
principalScreenView();
virtual ~principalScreenView() {}
virtual void setupScreen();
virtual void tearDownScreen();
virtual void setTimeDate(displayTimeDate_t nTimeDate);
protected:
};
我正在关注 YouTube 视频来执行此操作,但是使用结构而不是视频中的 int,我以为我不小心将该函数复制/粘贴到不同的文件中。但经过几个小时的尝试,我发现这与屏幕交互有关。我自己无法弄清楚错误。
我在STM论坛上问过,有人给了我答案。我正在尝试了解有关解决方案的更多信息。我的 C++ 书(很旧)谈到了虚函数,但不是这个小区别。网上有很多东西,但我可以找到一个解释。
答:
您的问题与虚函数无关,甚至不特定于 C++(这同样适用于 C)。
#1 和 #2 定义虚拟的方式有什么区别 函数 setTimeDate?
virtual void setTime(displayTime_t time); // #1 error
virtual void setTime(displayTime_t time){} // #2 correct
不同的是,#1 只是一个函数原型,而不是一个定义。它假定该函数是在其他地方定义的。如果未在任何地方提供函数定义,链接器将生成“未定义的引用”错误。
在 #2 中,您提供了一个函数体,它定义了一个空的(又名无操作)函数。{}
具体到函数,你可以指定它是纯的,即它没有任何实现,方法是在末尾添加:virtual
=0
virtual void setTime(displayTime_t time) = 0;
但是,如果它包含在类中,则会使该类抽象化,即您不能创建此类的变量。它只能用作基类。
评论
{}
virtual void setTime(displayTime_t time){}
{}
评论
virtual
virtual
virtual void setTime(displayTime_t time);
virtual
virtual
virtual void setTime(displayTime_t time) = 0;