【muduo】base库之 Types

一、类型转换

C++中有四种强制类型转换操作符:

  1. static_cast:这个是最经常使用的类型转换。凡是C++隐式执行的类型转换都能够用static_cast显式完毕。在隐式转换时有时编译器会有警告信息。可是显示转换就不会有。static是指编译时,转型失败的话就不能编译。
  2. const_cast:从名字能够看出和const有关,这个转换的作用是去除或加入const特性,它能够将一个const变量转换为非const变量,或将一个非const变量转换为const变量。
  3. dynamic_cast:这个是运行时检查该类型转换是否安全。被转换的类型必须是多态(即有虚函数)。dynamic 是指运行时,主要用于执行“安全的向下转型。
  4. interpret_cast:interpret意思为又一次解释。意思为将数据的二进制格式又一次解释,转型时不做任何检查。
  • 强制类型转换,往往是不安全的,这点要使用者去把握,去了解这种使用是不是安全。
  • 强制类型转换又是强大的,只要你能保证做的转换的正确性,那么它就是好用的

 

隐式类型转换:隐式类型转换是从小到大的转换。在数据类型上表现是少字节数据类型,转换成多字节数据类型,保证数据的完整性;在类上表现,从子类转换成父类,保证类对象功能的正常。

 

在同一继承体系中:

  upcast(向上转换 即子类转成父类):没有问题.因为父类的行为都包含在子类中;

  downcast(向下转换):有可能会出现问题,编译时可能不会发现.

 

下面说说常用的其它两种转型,取自 Google Chrome 的源码。

implicit_cast

template<typename To, typename From>
inline To implicit_cast(From const &f) {
  return f;
}

用法:

double d = 3.14;
int i = 3;
std::min(d, implicit_cast<double>(i));

implicit_cast 相较于其它转型的好处是:

  • 读代码的人可以立即就明白,这是一个简单的隐式转换。
  • implicit_cast仅仅能执行up-cast,相较于static_cast 更为安全

 

down_cast

down_cast 是在继承结构中往下转型(也就是将基类指针转换为派生类的指针,前提是基类指针指向的派生类对象,才能向下转型),这也正是down的含义,它是用来替代dynamic_cast 的,没有运行时检查,直接用static_cast 来做转型,从而提高性能。当然,使用场景也就受了限制,只有当你 100% 确定 From和To 的关系时,才能使用,否则后果自负。

template<typename To, typename From>
inline To down_cast(From* f) {
  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);
}

down_cast 的实现巧妙的使用了implicit_cast ,让编译器帮助做了类型检查,而 if(false) 条件保证了最终肯定会被编译器优化掉,所以对性能没有任何影响。

 

二、Types源代码

#ifndef MUDUO_BASE_TYPES_H
#define MUDUO_BASE_TYPES_H

#include <stdint.h>
#include <string.h>  // memset
#include <string>

#ifndef NDEBUG
#include <assert.h>
#endif

///
/// The most common stuffs.(最常见的东西)
///
namespace muduo
{

using std::string;

//简化了 memset 的使用
inline void memZero(void* p, size_t n)
{
  //将p中当前位置后面n个字节用0替换并返回p。
  memset(p, 0, n);
}

// Taken from google-protobuf stubs/common.h
//
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Author: kenton@google.com (Kenton Varda) and others
//
// Contains basic types and utilities used by the rest of the library.


// 使用 implicit_cast作为 static_cast 或者 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).

// 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 时,编译器将检查转换是否安全

// The From type can be inferred, so the preferred syntax for using
// implicit_cast is the same as for static_cast etc.:
//
//   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.

//用于在继承关系中,子类指针转化为父类指针(即up-cast 上转型);隐式转换
//将 From 转成了 To
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>(foo)) HandleASubclass2Object(foo);
// You should design the code some other way not to need this.

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语句永远不会被执行
  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

 

 

总结
  在程序设计中,主要是我们自己代码编写者要明确的知道当前是 down_cast 还是 up_cast , up_cast 那就使用implicit_cast ,down_cast 就用 down_cast 。


 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

潇湘夜雨~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值