c++ - 检查类是否派生自特定类(编译、运行时均可用)

标签 c++ class c++11 encapsulation

这样在例子上更容易解释,

class base {
//....
}

class derived1 : public base {
//...
}

在我的库中,有一个基类的指针。库的用户必须创建从 base 或 derived1 派生的类,并将指针分配给该类。

如何检查用户定义的类派生自哪个类?

最佳答案

我对提议的编译时 x 运行时解决方案有一些评论。除了评估它们的时间之外,is_base_ofdynamic_cast有不同的要求,他们的答案可能不同。

(1) 首先(正如其他人所指出的)使用 dynamic_cast 、基类和派生类必须是多态的(必须至少有一个 virtual 方法)。 is_base_of不要求类型是多态的。

(2) is_base_of 的操作数都是类型,而 dynamic_cast需要一个类型(在 < > 内)和一个对象(在 ( ) 内)。

(3) dynamic_castis_base_of可以根据继承类型( publicprotectedprivate )给出不同的答案(或者一个可以编译而另一个不能编译)。例如考虑:

struct B { virtual ~B() {} }; // polymorphic, so it can be used in a dynamic_cast
struct D1 : public B {};      // polymorphic by (public)  inheritance
struct D2 : private B {};     // polymorphic by (private) inheritance

D1 d1;
D2 d2;

我们有

static_assert(std::is_base_of<B, D1>::value, "");
static_assert(std::is_base_of<B, D2>::value, "");

assert(dynamic_cast<B*>(&d1));
assert(!dynamic_cast<B*>(&d2)); // Notice the negation.

实际上最后一行在 GCC 中产生编译器错误 (error: 'B' is an inaccessible base of 'D2')。 VS2010 会编译它(只产生类似于 GCC 错误消息的警告)。

(4) 可以通过异常处理技巧放宽对多态类的要求。考虑:

struct B { };             // not polymorphic
struct D1 : public B {};  // not polymorphic
struct D2 : private B {}; // not polymorphic

D1 d1;
D2 d2;

template <typename B, typename D>
const B* is_unambiguous_public_base_of(const D* obj) {
    try {
        throw obj;
    }
    catch (const B* pb) {
        return pb;
    }
    catch (...) {
    }
    return nullptr;
}

那么我们有

static_assert(std::is_base_of<B, D1>::value, "");
static_assert(std::is_base_of<B, D2>::value, "");

assert((is_unambiguous_public_base_of<B>(&d1)));
assert(!(is_unambiguous_public_base_of<B>(&d2))); // Notice the negation.

值得一提的是 is_unambiguous_public_base_of远比 dynamic_cast 慢并且(在下面的更新中提到的重命名之后,这变得更加明显)总是返回 nullptr对于沮丧:

B* b1 = &d1;
assert(dynamic_cast<D1*>(b1));        // Requires D1 and B to be polymorphic.
assert(!(is_unambiguous_public_base_of<D1>(b1))); // Notice the negation.

以下链接提供了关于此技巧的有点过时的引用:

Part 1 , Part 2code

免责声明:is_unambiguous_public_base_of 的实现以上只是说明这一点的草稿,它不处理 constvolatile适当的资格。

更新:在这篇文章的前一个版本中is_unambiguous_public_base_of被命名为my_dynamic_cast这是困惑的根源。所以我把它重命名为一个更有意义的名字。 (感谢 Jan Herrmann。)

关于c++ - 检查类是否派生自特定类(编译、运行时均可用),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18099241/

相关文章:

c++ - 在没有固定角度的图像上绘制旋转边界框

c++ - 标记为 `virtual final` 的基类方法是否会引入额外的开销?

c++ - 我可以对 Java 或 C++ 使用 Python 缩进样式吗?

Javascript - 在函数中传递 THIS 不起作用

c++ - std::map、std::set 和 std::priority_queue 中的比较器

c++ - 在关闭套接字之前发送数据包

java - 从 Pentaho Kettle 调用 Java 库

Python:对象作为另一个对象的参数

c++ - 调用可变类型的静态 constexpr 数组时 undefined reference

c++ - 通过其成员的地址激活嵌套 union 是否合法?