gpt4 book ai didi

c++ - 检查一个对象的类是否派生自 C++ 中另一个对象的类

转载 作者:行者123 更新时间:2023-11-30 04:41:14 25 4
gpt4 key购买 nike

如果我有对象 ab,我如何确定 a 的类是否继承自 b 的类?


背景:我有一个 C++ 库,我想为其编写一个 Python 绑定(bind)生成器。该库提供了一组从公共(public)基类派生的类。对于 Python 绑定(bind),我需要所有类的函数列表。我通过 nm -D myLibrary.so 得到了一个方法列表,但是缺少继承类的方法,例如风格

template<class WrappedClass>
class Wrapper: public WrappedClass {
public:
// ...
};

typedef Wrapper<ClassA> ClassB;

.所以我得到了像 ClassA 这样的类的所有功能,并且只想知道它们属于哪个 ClassB

我可以在运行时从库中获取所有可用类的名称列表,并且可以通过接受类名并提供该类型对象的工厂函数获取具有这些类型的对象。所以最后一 block 就是动态判断ClassB这样的类属于哪些类ClassA。因此问题。

PS:我原则上可以编写一个 C++ 代码生成器来生成测试代码,然后针对库进行编译以确定哪些类继承自哪些其他类。这将导致无法将我的代码与库一起编译但需要第二次编译的高成本。由于除了这个问题之外,我几乎可以解决这个问题,所以我非常希望有一个不同的解决方案。


PPS:有人告诉我在评论中使用 decltype。那行不通:

#include <iostream>
#include <type_traits>

struct A {};
struct B : A {};

int main() {
A* a = new A();
A* b = new B();
std::cout << std::boolalpha;
std::cout << "A, B: " << std::is_base_of<A,B>::value << std::endl;
std::cout << "a, b: " << std::is_base_of<decltype(a),decltype(b)>::value << std::endl;
std::cout << "*a, *b: " << std::is_base_of<decltype(*a),decltype(*b)>::value << std::endl;
std::cout << "a., B: " << std::is_base_of<decltype(a),B>::value << std::endl;
std::cout << "*a., B: " << std::is_base_of<decltype(*a),B>::value << std::endl;
return 0;
}
}

产量

A, B: true
a, b: false
*a, *b: false
a., B: false
*a., B: false

PPPS:建议使用一个答案

std::is_base_of_v<std::decay_t<decltype(*a)>, std::decay_t<decltype(*b)>>

.我无法让它工作:

#include <iostream>
#include <type_traits>

struct A {};
struct B : A {};

int main() {
A* a = new A();
A* b = new B();
std::cout << std::boolalpha;
std::cout << "A, B: " << std::is_base_of<A,B>::value << std::endl;
std::cout << "B, A: " << std::is_base_of<B,A>::value << std::endl;
std::cout << "*a, *b: " << std::is_base_of<std::decay_t<decltype(*a)>, std::decay_t<decltype(*b)>>::value << std::endl;
std::cout << "*b, *a: " << std::is_base_of<std::decay_t<decltype(*b)>, std::decay_t<decltype(*a)>>::value << std::endl;
return 0;
}

产量:

A, B: true
B, A: false
*a, *b: true
*b, *a: true

最佳答案

If I got objects a and b, how do I determine if the class of a inherits from the class of b?

回答提出的问题,std::is_base_of:

std::is_base_of_v<std::decay_t<decltype(*a)>, std::decay_t<decltype(*b)>>

在您的示例中,ab 实际上不是对象,而是指向对象的指针,因此您必须取消引用才能获得对对象的引用,以 decltype 获取类型,然后使用 std::decay_t 移除引用和 const 限定。

在C++中,对象既有静态类型也有动态类型。 std::is_base_of 适用于静态类型。对于动态类型,dynamic_cast 会告诉您这些类型是否相关,但是没有标准查询只能回答一个动态类型是否是另一个动态类型的基础。对于用另一种语言包装,静态类型似乎是更有趣的类型,可以调用哪些成员函数。

但是,您解决实际问题的方法存在缺陷。使用 nm 确定类的成员函数名称不会告诉您这些名称的可访问性或如何解析重载。 std::is_base_of 将回答所问的问题,但如果基类不可访问或不明确,它将返回 true,在这种情况下,基类的成员函数不会返回直接应用于派生。

假设您不想手动维护绑定(bind),最好的方法是找到可以生成它们的工具(例如 swig)或编写这样的工具(例如使用 python clang 绑定(bind))。

关于c++ - 检查一个对象的类是否派生自 C++ 中另一个对象的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59167480/

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