检测方法是否已被覆盖

编程入门 行业动态 更新时间:2024-10-21 10:12:27
本文介绍了检测方法是否已被覆盖的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

给定C ++基类指针,有没有办法检测某个虚拟方法是否已被覆盖?

Given a C++ base class pointer, is there a way to detect whether a certain virtual method has been overridden?

我正在写一种英语的口译员.我有一个基类来代表各种值类型的专门化值.这是一个简化的示例:

I'm writing an interpreter for a little language. I have a base class to represent values with specializations for the various value types. Here's a simplified example:

class Value { public: virtual bool CanBeString() const { return false; } virtual std::string GetAsString() const { throw std::logic_error("Value cannot be represented as a string."); } virtual bool CanBeInt() const { return false; } virtual int GetAsInt() const { throw std::logic_error("Value cannot be represented as an int."); } }; class StringValue : public Value { public: bool CanBeString() const override { return true; } std::string GetAsString() const override { return m_string; } private: std::string m_string; }; class IntValue : public Value { public: // Even though this is an integer, it can be represented as a string. bool CanBeString() const override { return true; } std::string GetAsString() const override { /* return string rep of m_int */ } bool CanBeInt() const override { return true; } int GetAsInt() const override { return m_int; } private: int m_int; };

解释器使用指向Value的指针,并在运行时进行类型检查.假设解释器具有一个值,并且它需要在该值上执行仅适用于int的操作.它将首先检查pValue->CanBeInt().如果为true,则解释器继续pValue->GetAsInt()并进行处理.如果该值与int不兼容,则报告类型错误.

The interpreter works with pointers to Values and does type-checking at runtime. Suppose the interpreter has a value and it needs to execute an operation on it that applies only to ints. It will first check pValue->CanBeInt(). If true, the interpreter proceeds with pValue->GetAsInt() and does the processing. If the value is not compatible with an int, it reports a type error.

GetAsXxx的基本实现不应执行.如果执行一个,则说明解释器中存在错误(它忘记首先检查类型).这些throw语句是要通知我修复解释器.我不不想因为正在解释的代码中的类型错误而抛出异常.

The base implementations of GetAsXxx should never be executed. If one is executed, it means there's a bug in the interpreter (it forgot to check the type first). Those throw statements are to signal me to fix the interpreter; I do not want to throw an exception because of a type error in the code that's being interpreted.

为了使向系统中添加新类型更容易(并且更不容易出错),我一直在尝试确定是否有一种方法可以消除派生类重写CanBeXxx的需要.能够检测相应的GetAsXxx方法是否已被覆盖.

In order to make it easier (and less error prone) to add new types to the system, I've been trying to determine if there's a way to eliminate the need for the derived classes to override the CanBeXxx by being able to detect if the corresponding GetAsXxx method has been overridden.

我的具体想法是将CanBeXxx方法更改为基类中定义的非虚拟方法,这些方法试图将GetAsXxx方法的成员函数指针与Value::GetAsXxx的成员函数指针进行比较.如:

My specific idea was to change the CanBeXxx methods to non-virtual ones defined in the base class that try to compare the member function pointer for the GetAsXxx method to the one for Value::GetAsXxx. As in:

bool CanBeInt() const { return &GetAsInt != &Value::GetAsInt; }

A,这不会编译,因为显然您无法获得已绑定方法的成员函数指针.这个想法或其他方法是否有变体,可以考虑到这一点?

Alas, this doesn't compile because apparently you can't get a member function pointer for a method that's already bound. Is there a variation on this idea or another approach that would allow for this little slice of reflection?

推荐答案

将成员方法指针分开进行比较是特定于编译器的,因为不同的编译器对方法指针的处理方式也不同.但是,您可以考虑采用另一种设计.它不会完全消除问题,但会对其进行一些简化,同时仍提供了将来添加更多类型的灵活性:

Pulling apart member method pointers to do comparisons is compiler-specific, as different compilers handle method pointers differently. However, there is an alternative design you might consider. It won't completely eliminate the problem, but it will simplify it a little, while still providing flexibility to add more types in the future:

const unsigned int CanBeInt = 1; const unsigned int CanBeString = 2; ... class Value { private: unsigned int flags; public: Value(unsigned int aflags) : flags(aflags) {} unsigned int GetFlags() const { return flags; } inline bool CanBeString() const { return (flags & CanBeString); } virtual std::string GetAsString() const { throw std::logic_error("Value cannot be represented as a string."); } inline bool CanBeInt() const { return (flags & CanBeInt); } virtual int GetAsInt() const { throw std::logic_error("Value cannot be represented as an int."); } }; class StringValue : public Value { public: StringValue() : Value(CanBeString) {} std::string GetAsString() const override { return m_string; } private: std::string m_string; }; class IntValue : public Value { public: // Even though this is an integer, it can be represented as a string. IntValue() : Value(CanBeInt | CanBeString) {} std::string GetAsString() const override { /* return string rep of m_int */ } int GetAsInt() const override { return m_int; } private: int m_int; };

if (pValue->CanBeInt()) { int val = pValue->GetAsInt(); ... } if (pValue->GetFlags() & CanBeInt) { int val = pValue->GetAsInt(); ... }

if (pValue->CanBeString()) { std::string val = pValue->GetAsString(); ... } if (pValue->GetFlags() & CanBeString) { std::string val = pValue->GetAsString(); ... }

另一个建议,例如@Beta建议:

Another option, like @Beta suggested:

class Value { public: virtual bool GetAsString(std::string &) const { return false; } virtual bool GetAsInt(int &) const { return false; } }; class StringValue : public Value { public: bool GetAsString(std::string &value) const override { value = m_string; return true; } private: std::string m_string; }; class IntValue : public Value { public: // Even though this is an integer, it can be represented as a string. bool GetAsString(std::string &value) const override { value = ...; return true; } bool GetAsInt(int &value) const override { value = m_int; return true; } private: int m_int; };

std::string val; if (!pValue->GetAsString(val)) throw std::logic_error("Value cannot be represented as a string.");

int val; if (!pValue->GetAsInt(val)) throw std::logic_error("Value cannot be represented as a int.");

更多推荐

检测方法是否已被覆盖

本文发布于:2023-11-08 07:40:17,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1568758.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:已被   检测方法

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!