1、C++提供了四个转换运算符:
- const_cast <new_type> (expression)
- static_cast <new_type> (expression)
- reinterpret_cast <new_type> (expression)
- dynamic_cast <new_type> (expression)
(1)const_cast
用法:const_cast<type>(expression)
<1>const_cast 去掉const属性:
const_cast<int*> (&num),常用,因为不能把一个const变量直接赋给一个非const变量,必须要转换。
<2>加上const属性:
const int* k = const_cast<const int*>(j),一般很少用,因为可以把一个非const变量直接赋给一个const变量,
<3>例如:
const int a = 1;
int & b = const_cast<int&>(a);
b = 2;
cout << a ;
cout << b;
先 打印1,后打印2
(2)static_cast
//待添加
(3)reinterpret_cast
//待添加
(4)dynamic_cast
//待添加
参考自以下别人的博客
https://www.cnblogs.com/tianzeng/p/9062074.html
https://www.cnblogs.com/ider/archive/2011/07/22/cpp_cast_operator_part2.html
https://blog.csdn.net/TanJiaLiang_/article/details/83992337
https://blog.csdn.net/anlian523/article/details/95751762
https://www.cnblogs.com/teng-IT/p/5981294.html
2、注意区别qt中的,QT框架提供的强制类型转换方法:
qobject_cast
qgraphicsitem_cast
qvariant_cast
(1)qobject_cast
函数原型:T qobject_cast ( QObject * object )
类似于标准C ++ dynamic_cast(),其优点是不需要RTTI支持,并且它可以跨动态库边界工作。
(2)qgraphicsitem_cast
场景视图Item类转换
(3)qvariant_cast
QVariant类型转换为实际的类型
参考自:https://www.cnblogs.com/MakeView660/p/11045437.html
3、另外以下摘抄自:
http://www.imooc.com/wenda/detail/538675
如果有侵权请留言或者私信联系删除
关于const_cast的几点疑问
慕田峪7331174 2019-04-14 10:33:49
来自《c++primer第5版》,我的疑问是粗体:
const_cast
const_cast只能改变运算对象的底层const
constchar*pc;
char*p=const_cast(pc);//正确:但通过p写值是未定义的后果
对于将常量对象转换成非常量对象的行为,我们一般称其为“去掉const性质”。一旦我们去掉了某个对象的const性质,编译器就不再阻止我们对该对象进行写操作了。如果对象本身不是一个常量,使用强制类型转换获得写权限是合法的行为。上面这句话是什么意思?是说
char*pc;
constchar*p=const_cast(pc);
用来对p写值是合法的行为吗?我觉得反过来才对吧?(我已经懂了,作者意思应该是说非常量constcast成常量后再constcast成非常量的这种情况是可以获得写权限的)然而如果对象是一个常量,在使用const_cast执行写操作就会产生未定义的后果。我想const_cast的目的就是用来对const对象写值,如果“通过p写值是未定义的后果”那么使用const_cast有什么用呢?
2 回答
首先,const修饰符加不加是会构成操作符重载的,与const对应的是volatile,统称为cv修饰符。我想constcast的目的就是用来对const对象写值,如果“通过p写值是未定义的后果”那么使用constcast有什么用呢?const_cast只是编译时的约定,而“通过p写值是未定义的后果”是运行时的问题,这2个约束不是一回事上面也说了“只有const_cast能改变表达式的常量属性,使用其他形式的命名强制类型转换改变表达式的常量都将引发编译器错误”,下面的例子却是你的例子是对的,因为你是用static_cast转换的#include
#include usingnamespacestd;
#include usingstd::string;
classMyClass
{
public:
voidtest()
{
cout<<"noneconstobject"<
}
voidtest()const
{
cout<<"constobject"<
}
voidtest()volatile
{
cout<<"volatileobject"<}
};
int main()
{
MyClass*a=newMyClass();
constMyClass*b=newMyClass();
volatileMyClass*c=newMyClass();
a->test();
b->test();
c->test();
MyClass*d=0;
//d=b;编译会报错,无法去掉const属性,需要
d=const_cast(b);
d->test();
system("Pause");
return0;
}
反对 回复2019-04-14
对于将常量对象转换成非常量对象的行为,我们一般称其为“去掉const性质”。一旦我们去掉了某个对象的const性质,编译器就不再阻止我们对该对象进行写操作了。如果对象本身不是一个常量,使用强制类型转换获得写权限是合法的行为。
上面这句话是什么意思?
答:即使const_cast可以去掉指针或引用的常量性(去const)得到非const的指针或引用,但使用转换后的这个指针或引用,去修改原本被声明为const的对象,会引发未定义行为。示例
constintj=3;//j声明为const常量
int*pj=const_cast(&j);
*pj=4;//用去const的指针去修改一个原本就是常量的j的值,undefinedbehavior!
如果j声明为intj=3;它不是一个常量,上面的代码就是合法并预期工作的。
我想constcast的目的就是用来对const对象写值,如果“通过p写值是未定义的后果”那么使用constcast有什么用呢?
答:如下用处:
最常见的,有一些人声明函数类型时,即使在函数里不修改指针的值,也不声明为const,典型的懒,比如voidlog(char*msg);明明只是用来把msg打印出来,但它就是不加上const。遇到这种情况,我们只好把手上的const指针转为非const再传给它,因为c++编译器不允许你直接把const指针直接丢给char*,会报错,而c编译比如gcc,只是产生一个warning而已。
这种我是在effectivec++看到的用法,示例代码:
classMyClass
{
charcached_data[10000];//shouldbemutable
boolcache_dirty;//shouldalsobemutable
public:
chargetData(intindex)const
{
if(cache_dirty)
{
MyClass*thisptr=const_cast(this);
update_cache(thisptr->cached_data);
}
returncached_data[index];
}
};
简言之,就是在一个const成员函数里,要修改没有声明为mutable的成员变量。
可以去掉volatile修饰的变量,具体作用有待了解。
上面也说了“只有const_cast能改变表达式的常量属性,使用其他形式的命名强制类型转换改变表达式的常量都将引发编译器错误”,下面的例子却是
static_cast(cp);//正确:字符串字面值转换成string类型
这不是自相矛盾么?
首先
只有const_cast能改变表达式的常量属性,使用其他形式的命名强制类型转换改变表达式的常量都将引发编译器错误
这句话的意思是说把表达从const转非const,或反过来,只能用const_cast,而其它的形式如
static_cast(cp);
这是不行的。
然后不能用const_cast改变表达式的类型
这句话是说用const_cast时,要转的类型跟被转的类型,要一致,只是有没有const修饰符的区别,如
const_cast(cp);
这是不行的,因为cp的类型是char*,跟string完全不同,如果cp为conststringcp那就可行。
但是staticcast(cp)是可行的,因为它没有改变const,它只是改变了类型,不属于上述constcast说的两种情况。
其实就是书本的内容浓缩了,然后把代码放一起节省篇幅,导致你误解了。
以上只是为学习总结的资料,如果有侵权请留言或者私信联系删除,我们尊重原创。