古月不傲 发表于 2021-1-12 16:46

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]
查看完整版本: implicit_cast与down_cast