implicit_cast与down_cast
本帖最后由 古月不傲 于 2021-1-12 16:47 编辑// Use implicit_cast as a safe version of static_cast or const_cast
// for upcasting in the type hierarchy (i.e. casting a pointer to Foo
// to a pointer to SuperclassOfFoo or casting a pointer to Foo to
// a const pointer to Foo).
// 使用 implicit_cast 替换static_cast | const_cast,因为它是向上类型转换的一个安全的版本
// (即,将一个子类指针转为基类指针 | 将一个Foo指针转为常量指针)
// When you use implicit_cast, the compiler checks that the cast is safe.
// Such explicit implicit_casts are necessary in surprisingly many
// situations where C++ demands an exact type match instead of an
// argument type convertable to a target type.
//
// 当你使用 implicit_cast时,编译器会检查转换是否安全
// 这种 implicit_casts转换在许多情况下都是必须的,例如C++需要一个精确的类型匹配,而不是隐式类型转换
//
// The From type can be inferred, so the preferred syntax for using
// implicit_cast is the same as for static_cast etc.:
// From参数可以推断出类型,所以 更推荐使用 implicit_cast 因为使用implicit_cast 就等价于static_cast等
//
// implicit_cast<ToType>(expr)
//
// implicit_cast would have been part of the C++ standard library,
// but the proposal was submitted too late.It will probably make
// its way into the language in the future.
// implicit_cast 本该是C++标准库的一部分,但是发布的太晚了
// 未来很可能会是C++中的一员
template<typename To, typename From>
inline To implicit_cast(From const &f)
{
return f;
}
// When you upcast (that is, cast a pointer from type Foo to type
// SuperclassOfFoo), it's fine to use implicit_cast<>, since upcasts
// always succeed.When you downcast (that is, cast a pointer from
// type Foo to type SubclassOfFoo), static_cast<> isn't safe, because
// how do you know the pointer is really of type SubclassOfFoo?It
// could be a bare Foo, or of type DifferentSubclassOfFoo.Thus,
// when you downcast, you should use this macro.In debug mode, we
// use dynamic_cast<> to double-check the downcast is legal (we die
// if it's not).In normal mode, we do the efficient static_cast<>
// instead.Thus, it's important to test in debug mode to make sure
// the cast is legal!
// This is the only place in the code we should use dynamic_cast<>.
// In particular, you SHOULDN'T be using dynamic_cast<> in order to
// do RTTI (eg code like this:
// if (dynamic_cast<Subclass1>(foo)) HandleASubclass1Object(foo);
// if (dynamic_cast<Subclass2>kkk(foo)) HandleASubclass2Object(foo);
// You should design the code some other way not to need this.
// 当你使用向上类型转换(也就是子类转父类,最好使用 implicit_cast,因为它总是成功)
// 当你使用向下类型转换时,应该使用 down_cast(static_cast是不安全的,因为你怎么知道指针的类型就是子类呢?)
// 调试版,down_cast使用dynamic_cast,发布版使用static_cast
template<typename To, typename From> // use like this: down_cast<T*>(foo);
inline To down_cast(From* f) // so we only accept pointers
{
// Ensures that To is a sub-type of From *.This test is here only
// for compile-time type checking, and has no overhead in an
// optimized build at run-time, as it will be optimized away
// completely.
if (false)
{
implicit_cast<From*, To>(0);
}
#if !defined(NDEBUG) && !defined(GOOGLE_PROTOBUF_NO_RTTI)
assert(f == NULL || dynamic_cast<To>(f) != NULL);// RTTI: debug mode only!
#endif
return static_cast<To>(f);
}
}// namespace muduo
#endif// MUDUO_BASE_TYPES_H
测试
#include <iostream>
#include <assert.h>
//#define NDEBUG
// #define GOOGLE_PROTOBUF_NO_RTTI
template<typename To, typename From>
To implicit_cast(From const &f)
{
return f;
}
template<typename To, typename From>
To down_cast(From *f)
{
#if !defined(NDEBUG) && !defined(GOOGLE_PROTOBUF_NO_RTTI)
assert(f == nullptr || dynamic_cast<To>(f) != nullptr);
#endif
return static_cast<To>(f);
}
class Parent
{
public:
virtual ~Parent() {}
virtual void print() = 0;
};
class Child : public Parent
{
public:
void print() override
{
printf("child\n");
}
};
// 运行上述实例函数并打印捕捉的异常
int main()
{
int a = 5;
double b = implicit_cast<double>(a);
printf("b = %lf\n", b);
// Parent *parent = implicit_cast<Parent *>(new Child());
// parent->print();
Parent *p;
//Child *child = static_cast<Child *>(p); // 编译正确
//child->print();
Child *child = implicit_cast<Child *>(p); // 编译错误
child->print();
return 0;
}
页:
[1]