您的位置:首页 > 编程语言 > C语言/C++

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

2017-07-31 11:39 316 查看
本文记录我对c++四种转换运算符的学习。参考的链接如下:[C++标准转换运算符const_cast]

前言

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

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

需要强调的是什么?

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

const_cast学习

用来干什么?

该运算符用来修改类型的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 = 0x7fff7d8678a4
paa = 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属性,但是,本质来说常量的值也没有改变,虽然这是编译器决定的。那么,这个东西到底有什么用???

首先,既然非常量指针指向常量之后是undefined behaviour,那么我们应该避免这种行为的发生,也就是我们要避免这种操作。2

const_cast用在什么地方呢?

在IBM的C++指南中还提到了另一种可能需要去const的情况:

我们定义了一个非const的变量,但用带con
4000
st限定的指针去指向它,在某一处我们突然又想修改了,可是我们手上只有指针,这时候我们可以去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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: