文档章节

Effective C++: static_cast, const_cast

SHIHUAMarryMe
 SHIHUAMarryMe
发布于 2016/01/29 23:12
字数 902
阅读 152
收藏 6
点赞 1
评论 0

const_cast<new_type>(expression):

 

直接看demo吧:

#include <iostream>
 
struct type {
    type() :i(3) {}
    void m1(int v) const {
        // this->i = v;                 // compile error: this is a pointer to const
        const_cast<type*>(this)->i = v; // OK as long as the type object isn't const
    }
    int i;
};
 
int main() 
{
   //case 1:
    int i = 3;                    // i is not declared const
    const int& cref_i = i; 
    const_cast<int&>(cref_i) = 4; // OK: modifies i
    std::cout << "i = " << i << '\n';
 
    //case 2:
    type t; // note, if this is const type t;, then t.m1(4); is UB
    t.m1(4);
    std::cout << "type::i = " << t.i << '\n';
 
    //case 3:
    const int j = 3; // j is declared const
    int* pj = const_cast<int*>(&j);
    *pj = 4;         // undefined behavior!
 
   //case 4:
    void (type::*mfp)(int) const = &type::m1; // pointer to member function
//  const_cast<void(type::*)(int)>(mfp); // compiler error: const_cast does not
                                         // work on function pointers
}

 

static_cast<new_type>(expression): 返回一个new_type类型的值.

1,Notice: 此时的new_type是既不是指针(pointer)也不是任何引用(reference)的情况.

如果 expression 和 new_type之间存在一个隐式(implicit)的转换关系(比如: int->double, short int->int..., 甚至是如果一个类类型(class)含有operator Type()我们都能完成从 expression 到 new_type的转换,或者是一个class含有一个implicit的构造函数此时我们相当于用expression构造该class),转换后返回的是一个 new_type类型的右值(rvalue).

2,Notice: 此时的new_type是一个类类型(class)的指针(pointer)或引用(reference),expression则是一个new_type的非虚基类的情况.

注意如果new_type是指针的话,传递进来的expression必定也是指针类型的变量,此时在static_cast内部会进行是否是nullptr的检查,如果是引用的话这不会检查。

无论是引用还是指针此时static_cast的最终目的都是从 基类(base-class)向派生类(derived-class)的转换.

3,Notice: 此时的new_type是一个右值引用类型(比如:int&&, std::vector<int>&&),此时expression可以是左值可以是右值.

当把一个lvalue(左值)转为右值(rvalue)的时候其实相当于对expression调用了std::move;

4,Notice: 此时的new_type为void;

当我们有一个不用的参数的时候编译器会经过就可以调用static_cast<void>(expression);消除编译器警告.

5,Notice: 取回存于void*指针的,原类型的指针.

6,Notice: 此时new_type为enum类型.

把一个enum(不管有没有指定class)类型的值转为它的underlying-type;

把一个指定了class的enum的类型转为一个没有指定class的enum类型.

7,如果一个指针指向派生类的成员(不管是数据成员,还是成员函数),且该成员是通过继承得到的也就是说该成员其实是基类中的那么我们可以通过static_cast,把该指针转为指向基类的该成员的指针.

8,指向任何类型的指针都能转为 void*;

 

#include <vector>
#include <iostream>
 
struct B {
    int m = 0;
    void hello() const {
        std::cout << "Hello world, this is B!\n";
    }
};
struct D : B {
    void hello() const {
        std::cout << "Hello world, this is D!\n";
    }
};
 
enum class E { ONE = 1, TWO, THREE };
enum EU { ONE = 1, TWO, THREE };
 
int main()
{
    // 1: initializing conversion
    int n = static_cast<int>(3.14); 
    std::cout << "n = " << n << '\n';
    std::vector<int> v = static_cast<std::vector<int>>(10);
    std::cout << "v.size() = " << v.size() << '\n';
 
    // 2: static downcast
    D d;
    B& br = d; // upcast via implicit conversion
    br.hello();
    D& another_d = static_cast<D&>(br); // downcast
    another_d.hello();
 
    // 3: lvalue to xvalue
    std::vector<int> v2 = static_cast<std::vector<int>&&>(v);
    std::cout << "after move, v.size() = " << v.size() << '\n';
 
    // 4: discarded-value expression
    static_cast<void>(v2.size());
 
    // 5. inverse of implicit conversion
    void* nv = &n;
    int* ni = static_cast<int*>(nv);
    std::cout << "*ni = " << *ni << '\n';
 
    // 6. array-to-pointer followed by upcast
    D a[10];
    B* dp = static_cast<B*>(a);
 
    // 7. scoped enum to int or float
    E e = E::ONE;
    int one = static_cast<int>(e);
    std::cout << one << '\n';
 
    // 8. int to enum, enum to another enum
    E e2 = static_cast<E>(one);
    EU eu = static_cast<EU>(e2);
 
    // 9. pointer to member upcast
    int D::*pm = &D::m;
    std::cout << br.*static_cast<int B::*>(pm) << '\n';
 
    // 10. void* to any type
    void* voidp = &e;
    std::vector<int>* p = static_cast<std::vector<int>*>(voidp);
}

 

 

 

© 著作权归作者所有

共有 人打赏支持
SHIHUAMarryMe
粉丝 12
博文 165
码字总数 138772
作品 0
武汉
程序员
[从C到C++] 1.7 C++ 强制类型转换

[toc] 在C++语言中新增了四个关键字staticcast、constcast、reinterpretcast和dynamiccast。这四个关键字都是用于强制类型转换的。我们逐一来介绍这四个关键字。 1) static_cast 在C++语言中...

wu_being ⋅ 06/16 ⋅ 0

C++与类型转换相关的四个关键字

C++与类型转换相关的四个关键字有:constcast、staticcast、dynamiccast、reinterpretcast C风格的强制类型转换(Type Cast)很简单,不管什么类型的转换统统是: TYPE b = (TYPE)a。 C++风格的...

Jim-he ⋅ 03/28 ⋅ 0

C++转型操作符

转:http://www.cnblogs.com/hazir/archive/2012/04/14/2447251.html 旧式的C转型方式,几乎允许你将任何类型转换为任何其它类型,有其自身的缺陷,表现在以下两方面: 不能更精确地指明其转...

长征2号 ⋅ 2017/08/18 ⋅ 0

QT开发(十)—— C++/Qt 开发过程中的一些技巧性总结

我会不定期的把我发现的一些小技巧都总结下来,这样自己就算忘记了,翻翻博客也能找回来,也是极好的。 一.C++ 1.变量的修饰 auto:属于一次性存储,其存储空间可被若干变量重复覆盖使用 regi...

qq_26787115 ⋅ 05/08 ⋅ 0

绕开“陷阱“,阿里专家带你深入理解C++对象模型的特殊之处

摘要:本文介绍了C++对象模型的特殊之处,包括与C兼容的朴素模型,以及能支持多态的虚表模型,同时还带大家了解了构造函数与析构函数相关的一些特性与陷阱。这些内容能够帮助大家更好地学习和...

nirvanalucky ⋅ 04/25 ⋅ 0

google的protobuf库

这篇文章将讲述如何使用google的protobuf库实现一个RPC service,就实现一个最简单的service吧:echo.文章对应的代码都可以在eventrpc中找到,写下这篇文章时的svn revision是138. 1) 定义协议首...

moki_oschina ⋅ 06/06 ⋅ 0

dynamic_cast和static_cast的异同

dynamiccast和staticcast是C++中的运行时类型转换运算符,代码如下: 1、对于有继承关系的两个类: (1)子类转成父类dynamiccast和staticcast都没有问题. (2)父类转成子类,dynamiccast要求父类...

技术小甜 ⋅ 2017/11/16 ⋅ 0

C++ 惯用法: const 常量和字面量

原文:C++ 惯用法: const 常量和字面量 作者:Breaker C++ 中 const 关键字、常量和字面量的惯用法 关键字:const, enum, constcast, constiterator, mutable, 左值, 字面量 本质和非本质上的...

晨曦之光 ⋅ 2012/05/23 ⋅ 0

Java程序员如何高效而优雅地入门C++

Java程序员如何高效而优雅地入门Cpp,由于工作需要,需要用C++写一些模块。关于C++ 的知识结构,虽说我有过快速学习很多新语言的经验,但对于C++ 我也算是老手,但也还需要心生敬畏,本文会从...

小欣妹妹 ⋅ 04/23 ⋅ 0

MFC中Spin control的使用

在编写一个工具时需要对经纬度进行微调,经纬度使用度分秒的格式来呈现的。想到了用控件 Spin Control 来实现。现对这个控件的用法做一个简要的回顾。 新建一个MFC基于对话框的应用程序,工程...

yousss ⋅ 04/24 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

10个免费的服务器监控工具

监控你的WEB服务器或者WEB主机运行是否正常与健康是非常重要的。你要确保用户始终可以打开你的网站并且网速不慢。服务器监控工具允许你收集和分析有关你的Web服务器的数据。 有许多非常好的服...

李朝强 ⋅ 21分钟前 ⋅ 0

压缩工具之zip-tar

zip 支持目录压缩。使用yum安装zip包,使用yum安装unzip包 zip 1.txt.zip 1.txt #将1.txt文件压缩,新生成的压缩文件为1.txt.zip,原文件保留 zip -r 123.zip 123/ #-r对目录操作。将123/目录...

ZHENG-JY ⋅ 21分钟前 ⋅ 0

Dubbo @Activate注解使用和实现解析

Activate注解标识一个扩展是否被激活和使用,可以放在定义的类上和方法上,dubbo用它在SPI扩张类定义上,标识这个扩展实现激活的条件和时机,先看下定义: /** * Activate * <p/> * ...

哲别0 ⋅ 28分钟前 ⋅ 0

6.5 zip压缩工具 tar打包 打包并压缩

1.tar tar命令格式 [-zjxcvfpP] filename tar -z:表示同时用gzip压缩。 -j:表示同时用bzip2压缩。 -J:表示同时用xz压缩。 -x:表示解包或者解压缩。 -t:表示查看tar包里的文件。 -c:表示建...

oschina130111 ⋅ 30分钟前 ⋅ 0

Linux系统工程狮养成记

如今的社会,随着时代的发展,出现了很多职业,像电子类,计算机类的专业,出现了各种各样的工程师,有算法工程师,java工程师,前端工程师,后台工程师,Linux工程师,运维工程师等等,不同...

六库科技 ⋅ 37分钟前 ⋅ 0

Linux 机器的渗透测试命令备忘表

如下是一份 Linux 机器的渗透测试备忘录,是在后期开发期间或者执行命令注入等操作时的一些典型命令,设计为测试人员进行本地枚举检查之用。 此外,你还可以从这儿(https://gbhackers.com/c...

寰宇01 ⋅ 38分钟前 ⋅ 0

windows 安装java开发环境,配置jdk

下载jdk安装文件 链接:https://pan.baidu.com/s/1UEKPjnAdMqNj612B39Pfsg 密码:ipqx 如果javac无法使用 1,检查环境变量名称中是否有空格。。。,去除后即可 2,将JAVA_HOME替换为原始路径...

阿豪boy ⋅ 40分钟前 ⋅ 0

简析log4j的实现方式

刚加入新公司,对日志的要求比较严格,对此特意花了几天时间看了一下log4j的源码,大概了解了一下log4j的实现方式,总结如下: log4j的实现分为两个步骤:log4j.xml的加载,logger的使用 这里...

zdatbit ⋅ 今天 ⋅ 0

win环境下jdk7与jdk8共存配置

1.jdk安装包 jdk安装包 安装步骤略 2.jdk等配置文件修改 在安装JDK1.8时(本机先安装jdk1.7再安装的jdk1.8),会将java.exe、javaw.exe、javaws.exe三个文件copy到了C:\Windows\System32,这...

泉天下 ⋅ 今天 ⋅ 0

windows profesional 2017 build problem

.net framework .... https://stackoverflow.com/questions/43330915/could-not-load-file-or-assembly-microsoft-build-frameworkvs-2017...

机油战士 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部