gpt4 book ai didi

c++ - 什么是处理类的元方面的适当接口(interface)?

转载 作者:塔克拉玛干 更新时间:2023-11-03 08:00:19 26 4
gpt4 key购买 nike

我正在寻找一些建议,以了解什么是处理 about 类(处理类)的方面的适当接口(interface),但它们不是他们正在处理的实际类的一部分(元方面)。这需要一些解释......

在我的具体示例中,我需要实现一个自定义 RTTI 系统,它比 C++ 提供的系统稍微复杂一些(我不会深入探讨为什么需要它)。我的基本对象是 FooBase并且这个基类的每个子类都关联一个 FooTypeInfo对象。

// Given a base pointer that holds a derived type,
// I need to be able to find the actual type of the
// derived object I'm holding.
FooBase* base = new FooDerived;

// The obvious approach is to use virtual functions...
const FooTypeInfo& info = base->typeinfo();

使用虚函数来处理对象的运行时类型对我来说并不合适。我倾向于将对象的运行时类型视为超出类范围的东西,因此它不应该是其显式接口(interface)的一部分。下面这个界面让我舒服了很多……

FooBase* base = new FooDerived;
const FooTypeInfo& info = foo::typeinfo(base);

然而,即使接口(interface)不是类的一部分,实现仍然必须使用虚函数,以便它工作:

class FooBase
{
protected:
virtual const FooTypeInfo& typeinfo() const = 0;
friend const FooTypeInfo& ::foo::typeinfo(const FooBase*);
};

namespace foo
{
const FooTypeInfo& typeinfo(const FooBase* ptr) {
return ptr->typeinfo();
}
}

你认为我应该使用第二个接口(interface)(感觉更适合我)并处理稍微复杂的实现,还是应该使用第一个接口(interface)?


@Seth Carnegie

This is a difficult problem if you don't even want derived classes to know about being part of the RTTI ... because you can't really do anything in the FooBase constructor that depends on the runtime type of the class being instantiated (for the same reason you can't call virtual methods in a ctor or dtor).

FooBase是层次结构的公共(public)基础。我还有一个单独的CppFoo<>减少样板文件数量并使类型定义更容易的类模板。还有一个PythonFoo使用 Python 派生对象的类。

template<typename FooClass>
class CppFoo : public FooBase
{
private:
const FooTypeInfo& typeinfo() const {
return ::foo::typeinfo<FooClass>();
}
};

class SpecificFoo : public CppFoo<SpecificFoo>
{
// The class can now be implemented agnostic of the
// RTTI system that works behind the scenes.
};

可以在此处找到有关系统工作原理的更多详细信息:
https://stackoverflow.com/a/8979111/627005

最佳答案

您可以通过 typeid 将动态类型与静态类型关联起来关键字和使用返回 std::type_info对象作为识别手段。此外,如果您申请 typeid在专门为此目的创建的单独类(class)上,它对您感兴趣的类(class)完全没有干扰,尽管他们的名字仍然必须提前知道。重要的是 typeid应用于支持动态多态性的类型 - 它必须有一些 virtual功能。

例子如下:

#include <typeinfo>
#include <cstdio>

class Base;
class Derived;

template <typename T> class sensor { virtual ~sensor(); };

extern const std::type_info& base = typeid(sensor<Base>);
extern const std::type_info& derived = typeid(sensor<Derived>);

template <const std::type_info* Type> struct type
{
static const char* name;

static void stuff();
};

template <const std::type_info* Type> const char* type<Type>::name = Type->name();

template<> void type<&base>::stuff()
{
std::puts("I know about Base");
}

template<> void type<&derived>::stuff()
{
std::puts("I know about Derived");
}

int main()
{
std::puts(type<&base>::name);
type<&base>::stuff();

std::puts(type<&derived>::name);
type<&derived>::stuff();
}

不用说,因为std::type_info是适当的对象,并且它们是唯一且有序的,您可以在集合中管理它们,从而删除从接口(interface)查询的类型:

template <typename T> struct sensor {virtual ~sensor() {}};

struct type
{
const std::type_info& info;

template <typename T>
explicit type(sensor<T> t) : info(typeid(t))
{};
};

bool operator<(const type& lh, const type& rh)
{
return lh.info.before(rh.info);
}

int main()
{
std::set<type> t;
t.insert(type(sensor<Base>()));
t.insert(type(sensor<Derived>()));

for (std::set<type>::iterator i = t.begin(); i != t.end(); ++i)
std::puts(i->info.name());
}

当然,您可以根据需要混合搭配两者。

两个限制:

  • 这里没有真正的内省(introspection)。您可以将其添加到 template struct sensor通过巧妙的元编程,这是一个非常广泛的主题(有时令人费解)。
  • 必须事先知道您要支持的所有类型的名称。

一种可能的变体是添加 RTTI“框架 Hook ”,例如 static const sensor<Myclass> rtti_MyClass;到类名已知的实现文件,让构造函数完成工作。此时它们还必须是完整类型才能在传感器中进行内省(introspection)。

关于c++ - 什么是处理类的元方面的适当接口(interface)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8989066/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com