c++学习-类型转换运算符

来源:互联网 发布:4g不含漫游支持网络 编辑:程序博客网 时间:2024/04/28 06:23

本文记录我对c++四种转换运算符的学习。参考的链接如下:[C++标准转换运算符const_cast]

前言

  1. 既然c语言提供隐式和显示的两种类型转换方式,为什么c++又要提供这四种类型转换运算符呢?

    C++相比于C是一门面向对象的语言,面向对象最大的特点之一就是具有“多态性(Polymorphism)”。很显然,c语言的类型转换没有覆盖的多态的特性,所以c++再次提出统一的四种类型转换运算符,要覆盖面向对象的特性。还有就是对传统运算符的代替,以便做到统一。

  2. 需要强调的是什么?

    指针和引用的类型转换是学习的重中之重。

const_cast学习

  1. 用来干什么?

该运算符用来修改类型的const或volatile属性.
一、常量指针被转化成非常量的指针,并且仍然指向原来的对象;
二、常量引用被转换成非常量的引用,并且仍然指向原来的对象;
三、const_cast一般用于修改底指针。如const char *p形式。

总结:const_cast一半作用于指针,用来去除指针的const属性。

2 . 例子

对于const变量,我们不能修改它的值,这是这个限定符最直接的表现。但是我们就是想违背它的限定希望修改其内容怎么办呢?

方法一

const int aa = 10;int modifier = aa;modifier = ...;

显然,由于原变量和新变量具有不同的内存空间,所以无法进行修改。

方法二

只有用指针或者引用,让变量指向同一个地址才是解决方案。

#include <stdio.h>int main( void ){    const int aa = 0;    int* paa = &aa;    *paa = 5;    printf( "aa = %d\n", aa );    printf( "*paa = %d\n", *paa);    return 0;}/*warning:main.c:12:13: warning: initialization discards ‘const’ qualifier from pointer target type [enabled by default]  int* paa = &aa;             ^aa = 5*paa = 5*/

上面的代码用c实现,用gcc编译。
会警告,但是可以执行,确实达到了效果。太可怕了!!!

上面的代码如果采用c++,用g++编译是过不去的。这么看c++还是比较靠谱的。

#include <cstdio>int main( void ){    const int aa = 0;    int* paa = &aa;    *paa = 5;    printf( "aa = %d\n", aa );    printf( "*paa = %d\n", *paa);    return 0;}/*main.cpp: In function ‘int main()’:main.cpp:12:14: error: invalid conversion from ‘const int*’ to ‘int*’ [-fpermissive]  int* paa = &aa;              ^*/

方法三

采用const_cast,对指针进行转换!消除原来指针的const属性。

#include <cstdio>#include <iostream>int main( void ){    const int aa = 0;    int* paa = const_cast<int*>(&aa); // const_cast    *paa = 5; // (Undefined Behavior),编译器决定如何处理    printf( "aa = %d\n", aa );    printf( "*paa = %d\n", *paa);    std::cout << "&aa = " << &aa << std::endl;    std::cout << "paa = " << paa << std::endl;    return 0;}/*aa = 0*paa = 5&aa = 0x7fff7d8678a4paa = 0x7fff7d8678a4奇怪了!!!地址一样,值不一样!*/

采用const_cast之后,代码确实可以编译通过!但是,结果确实令人感到奇怪的。
先说第一点:

const_cast实现原因就在于C++对于指针的转换是任意的,它不会检查类型,任何指针之间都可以进行互相转换。那么这是为什么呢?为什么c++的指针不同类型可以任意想换转换?我猜想是因为他们都是32位地址(cpu32位),所以,类型转换只是改变编译器看他们的方式罢了。

值为什么不变,我认为这是对的。证明c++还是比c在这里要优秀,它避免了常量被改的情况,及时还有指针真相它也不行。

当然,下面的代码也是可以的:

#include <cstdio>#include <iostream>int main( void ){    const int aa = 0;    int* paa = (int*)(&aa);    *paa = 5;    printf( "aa = %d\n", aa );    printf( "*paa = %d\n", *paa);    std::cout << "&aa = " << &aa << std::endl;    std::cout << "paa = " << paa << std::endl;    return 0;}

总结

从上面的代码也看出来,const_cast旨在消除指针的const属性,但是,本质来说常量的值也没有改变,虽然这是编译器决定的。那么,这个东西到底有什么用???


  1. 首先,既然非常量指针指向常量之后是undefined behaviour,那么我们应该避免这种行为的发生,也就是我们要避免这种操作。2
  2. const_cast用在什么地方呢?

在IBM的C++指南中还提到了另一种可能需要去const的情况:
我们定义了一个非const的变量,但用带const限定的指针去指向它,在某一处我们突然又想修改了,可是我们手上只有指针,这时候我们可以去const来修改了。
还有一种情形如下,当一个接口需要非常量指针的时候,但是你只有常量指针。需要转换给他!
#include <iostream>using namespace std;void print (char * str){  cout << str << '\n';}int main () {  const char * c = "sample text";  print ( const_cast<char *> (c) );  return 0;}
原创粉丝点击