用 C++ 实现接口?
Posted
技术标签:
【中文标题】用 C++ 实现接口?【英文标题】:Implement an interface in C++? 【发布时间】:2013-01-06 19:56:58 【问题描述】:我想实现我在 C++ 项目的引擎 (Unity3D) 中看到的行为。
以下代码是 C#(Unity 的语言):
using UnityEngine;
using System.Collections;
public class example : MonoBehaviour
void Update()
//Update is called every frame
由于我无法访问 MonoBehavior 源,我只能猜测 Update() 是一个可以像这样实现的虚函数。
我想在 C++ 中复制相同的行为。在main()
中有一个循环,一个超级对象将在该循环中调用它的Update()
方法,它的所有子对象都应该继承这个超级对象,并有可能实现Update()
并使用它。
我知道这是一个模棱两可的问题,但我到处寻找答案却没有找到答案。
这是一个例子:
class Base
public:
virtual void Update();
;
class Object: public Base
public:
void Update();
;
void main()
Base* base;
while(1)
base->Update();
结果应该是应该通过Base调用Object的Update()。我是 100% 上面的代码不起作用,这就是为什么我需要一些想法。
【问题讨论】:
是的,它是模棱两可的。我无法理解。有没有更全面的例子? Unity 似乎对方法名称使用反射和约定来查找类实现的方法。我不确定您是否可以在 C++ 中复制它。你确定你想要这个,或者实际上是在问如何创建一个虚拟方法并在 C++ 中覆盖它? 我正在开发一个项目,其中包含许多需要 Update() 的对象以及它的完成方式,通过继承和虚拟化将更新深入到对象。我希望能够创建一种更通用的方法,比如 Unity,但我发现它相当复杂。 【参考方案1】:C++ 没有接口。您使用纯虚方法创建一个抽象类。
class MonoBehaviour
virtual void Update() = 0;
;
class your_class : MonoBehaviour
void Update()
// implement here.
;
【讨论】:
这不是 Unity 所做的。抽象类没有派生类覆盖的虚拟方法。它是实现方法的派生类,Unity使用反射来找到它。另一方面,您的答案可能是 OP 要求的答案;这个问题模棱两可。 C++ 不支持反射。 garret.ru/cppreflection/docs/reflect.html【参考方案2】:可能存在子类方法和基类方法的签名不相同,即它们具有相同的名称但返回不同的东西或具有不同的参数。这是始终调用基类方法的一种方式。
或者你可能只是在主函数中构造基类对象而不是子类对象。在 main 函数中放置一个中断来检查您正在为其调用 Update 的对象的实际类型。
您发布的代码应该可以正常工作。基类是否是抽象的并不重要。为了便于实现子类,我更喜欢使其具体化并在应该为 = 0 的方法中抛出异常(我不必从一开始就实现完整的行为,只需要我关注的方法和我正在测试;所以它会逐步进行)。
是的,坚持公共继承。
编辑: 或者,如果您有这样的事情,可能会涉及到对象切片:
Derived* d_ptr = new Derived();
Base b = *d_ptr; // object slicing, d's methods will become Base methods;
Base* b_ptr = &b;
b_ptr->Update(); // will call Base::Update()
【讨论】:
【参考方案3】:首先要做的事情。您提供的示例首先不起作用,因为您忘记了指针的实例化。你的意思可能是这样的:
Base* base = new Object;
while(1)
base->Update();
现在解决这个问题。这个概念应该如您所愿。如果 Update 覆盖了其他人已经指出的 base 中的虚函数,则应在 Object 类中调用 Update。在c++11
中有一个整洁的东西叫做override
。它是您在函数声明之后放置的关键字,您希望覆盖基中的某些虚函数。使用override
是一个好习惯,因为如果您尝试使用override
非虚拟函数,编译器会抱怨。这减少了代码出错的可能性。
【讨论】:
以上是关于用 C++ 实现接口?的主要内容,如果未能解决你的问题,请参考以下文章
如何用C++实现支持HTTPS的RESTful WebServer
在 C++11 或以上,有没有办法通过 lambda 实现单方法纯虚拟 C++ 接口?