【问题标题】:How can I check the types of derived classes? (C++ Instanceof)如何检查派生类的类型? (C++ 实例)
【发布时间】:2020-05-20 19:42:16
【问题描述】:

假设我有一些基本抽象类和三个不同的类来派生和实现其方法。是否有像 C# 中的“类型”对象?或者换句话说,我如何获取所有这些类的实例?

#ModuleBase.cpp
class ModuleBase {

};

#Module1.cpp
class Module1 : public virtual ModuleBase {

};

#Module2.cpp
class Module2 : public virtual ModuleBase {

};

#Module3.cpp
class Module3 : public virtual ModuleBase {

};

【问题讨论】:

  • C++ 没有反射。 (还)
  • @MutexMorgan 没有内置功能(对于这两件事)。欢迎使用 C++。 :P
  • 基类如何知道它的派生类?想想像谷歌的代码库有数百万个类的代码库,编译器必须遍历所有类才能找到派生类
  • 你不能在 C++ 中做到这一点。您可以通过 RTTI(启用 dynamic_cast 的东西)找到​​有关类型 (std::type_info) 的非常基本的信息,但您无法了解其父类(复数,因为 C++ 允许多重继承)或派生的类从中。当然,有一些方法可以显式将类注册为公共基类的派生类,但这是您必须在代码中执行的操作。这是一个:web.archive.org/web/20100618122920/http://meat.net/2006/03/…

标签: c++ inheritance virtual-inheritance


【解决方案1】:

您可以创建instanceof 之类的方法,这些方法可以使用模板检测对象的类型,而std::is_base_of (1) 或dynamic_cast 仅适用于多态对象(2)。

1 Live sample

template<typename Base, typename T> inline bool instanceof(const T) {
   return is_base_of<Base, T>::value;
}
int main() {
   Module1 module;
   if(instanceof<Module1>(module)) {
      cout << "Module1" << endl;
   }
   if(instanceof<Module2>(module)) {
      cout << "Module2" << endl;
   }
   if(instanceof<ModuleBase>(module)) {
      cout << "ModuleBase" << endl;
   }
}

2 Live sample

class ModuleBase { public: virtual ~ModuleBase(){} };

template<typename T> inline bool instanceof(const ModuleBase * base) {
   return dynamic_cast<const T*>(base);
}
int main() {

   Module1* module = new Module1();

   if(instanceof<Module1>(module)) {
      cout << "Module1" << endl;
   }
   if(instanceof<Module2>(module)) {
      cout << "Module2" << endl;
   }
   if(instanceof<ModuleBase>(module)) {
      cout << "ModuleBase" << endl;
   }
}

对象的类型为ModuleBaseModule1。我认为你可以通过这些实现你所需要的。

【讨论】:

    【解决方案2】:

    除了其他答案之外,您还可以生成一些 C++ 代码来做您想做的事情。例如,考虑使用build automation 工具中的GPP(例如Makefile)或编写一个简单的AWKGuilePython 脚本来执行您想要的操作(或上面的一些临时C++ 生成器@ 987654326@,灵感来自SWIG),并根据您的需要生成一些 C++ 代码。我过时的 GCC MELT 在 Linux 上(在运行时动态地)这样做了。

    Qt 有一个 meta-object 协议正是这样做的。您可能会从它的 moc(它是开源的)生成 C++ 代码中获得灵感。

    还请查看正在进行的(但在 2020 年 2 月-处于萌芽阶段)RefPerSys 项目。我们想使用这些想法,并开始实施它们。请注意,在 Linux 上 dlopen 可以被调用数千次 in practice,在通过编译生成的临时 C++ 代码生成的共享对象上。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-16
      • 1970-01-01
      • 2011-05-04
      • 2011-02-01
      • 1970-01-01
      相关资源
      最近更新 更多