【问题标题】:Run time type information of base and derived classes基类和派生类的运行时类型信息
【发布时间】:2011-11-09 18:53:22
【问题描述】:

我正在尝试扩展一些我无权访问的类的功能。

基本上,我正在尝试创建一个 toString/toXML 方法来进行日志记录。我想创建一个单例(本质上是一个地图),我可以在其中注册不同的功能并让它们以某种方式在全球范围内可用,所以我可以拥有类似string Singleton::toString(void* or abstractObject*) 的东西,它会根据类型从地图中选择正确的方法.

虽然我可以使用 typeid 获取类型信息,但我希望能够为基类实现它,然后让所有派生类使用该方法,除非我有一个“更接近”/更合适的方法。

这可能吗,或者我应该改用其他方法(模板可以做到这一点)吗?不幸的是,我无法访问有问题的类,因为它们中的大多数来自 3rd 方库。

【问题讨论】:

  • 如果他们在第 3 方库中,abstractObject* 将如何帮助您? abstractObject 是否已经作为类型存在?
  • 大多数库都派生自(每个都有自己的)基础对象。我更喜欢一个通用的解决方案,但如果通过库/基础对象拆分它可以实现,它可能是一个可行的,虽然丑陋的解决方案。
  • 大多数类(甚至是第 3 方)都是通过 operator<< 序列化的。尝试使用它,看看它是否将自己打印到流中。
  • 这不是关于序列化,而是关于创建一个合理的日志输出。虽然大多数类确实有一些 toString 方法或流操作符,但它们通常会为调试日志文件生成太多(序列化对象)或很少(仅名称或值)输出。

标签: c++ rtti


【解决方案1】:

我发现以下是一种非常简单的方法来跟踪我定义的基结构和派生结构或类的类型。

_kind 不必是字符串。事实上,它可能应该是一个枚举。但是,由于我在设计这个程序时正在设计一个相当高级的程序,所以字符串对我来说已经足够快了。

struct base
{
protected:
    string _kind;
public:
    base()
    {
        _kind = "base";
    }

    ~base()
    {
    }

    string kind()
    {
        return _kind;
    }
}
struct derived : base
{
    derived()
    {
        _kind = "derived";
    }
    ~derived()
    {
    }
}

对于内置结构,也许重载 toString 和 toXML 方法并让编译器决定?

string toString(structure1 A)
{
...
}
string toString(structure2 A)
{
...
}

这对于派生结构可能会有些混乱,但是我认为编译器会选择叶子结构作为类型而不是基础。

例如,如果您有 A : B : C : D 类型,并且为 C 和 A 定义了函数 f。如果您输入 B 类型的变量,那么它应该自动类型转换为 A。如果您输入 a C 类型的变量,那么它将使用 C 类型的函数。如果输入 D 类型的变量,则应将其自动类型转换为 C 类型,然后调用 C 函数。

您也可以尝试基本上做同样事情的模板。

template <class t>
string toString(t A)
{
...
}

干杯, 内德

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-08
    • 2010-12-13
    • 1970-01-01
    • 1970-01-01
    • 2016-10-17
    • 1970-01-01
    • 2018-07-31
    • 2020-06-01
    相关资源
    最近更新 更多