kha*_*vah 8 c++ encapsulation class c++11
这样一个例子更容易解释,
class base {
//....
}
class derived1 : public base {
//...
}
Run Code Online (Sandbox Code Playgroud)
在我的库中,有一个基类指针.库的用户必须创建从base或derived1派生的类,并分配指向该类的指针.
如何检查从哪个类派生的用户定义类?
Cas*_*eri 11
我对拟议的编译时x运行时解决方案有一些评论.除了评估它们,is_base_of
并且dynamic_cast
有不同的要求,它们的答案可能不同.
(1)首先(正如其他人所指出的)使用dynamic_cast
,基类和派生类必须是多态的(必须至少有一个virtual
方法).is_base_of
不要求类型是多态的.
(2)操作数is_base_of
都是类型,而dynamic_cast
需要类型(内部< >
)和对象(内部( )
).
(3) dynamic_cast
并且is_base_of
可以给出不同的答案(或者一个可以编译而另一个没有),具体取决于继承的类型(public
vs protected
或private
).例如考虑:
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;
Run Code Online (Sandbox Code Playgroud)
我们有
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.
Run Code Online (Sandbox Code Playgroud)
实际上,最后一行在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;
}
Run Code Online (Sandbox Code Playgroud)
然后我们有
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.
Run Code Online (Sandbox Code Playgroud)
值得一提的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.
Run Code Online (Sandbox Code Playgroud)
这一招有点过时引用是在这里.
免责声明:上述实施is_unambiguous_public_base_of
只是一个草案,以表明它并没有正确处理const
和volatile
资格.
更新:在这篇文章的先前版本中is_unambiguous_public_base_of
被命名my_dynamic_cast
,这是一个混乱的来源.所以我把它重命名为一个更有意义的名字.(感谢Jan Herrmann.)
归档时间: |
|
查看次数: |
24466 次 |
最近记录: |