由于本人是技术白痴,所以有许多问题,都不知道,所以很多简单的问题也写里进来;
一个是关于类型的转换:到现在一直用的都是c语言里的强制转换,知道c++里有强制转换的函数,但是不记得怎么使了,所以重新把基础的东西再记一遍吧;
强制转换有四种:
dynamic_cast:这个类型转换是将基类类型对象的引用或者指针转换为同一继承层次中其他类型的引用或者指针。
如果绑定到引用或者指针的对象不是目标类型对象的话,则转换失败,转换失败返回参数是0;并且抛出一个bad_cast类型的异常。
作为例子,假定Base是至少带一个虚函数的类,并且Derived类派生于Base类。如果有一个名为basePtr的指向Base的指针,就可以像这样在运行时将他强制转换为指向Dervied的指针:
if( Derived *derivedPtr = dynamic_cast<Derived*>(basePtr) )
{}
else
{}
上面的例子使用的是指针的,dynamic_cast也可以将基类引用转换为派生类引用,这里如果转换失败,那么将抛出一个bad_cast异常,这里修改上面的程序:
void f(const Base &b)
{
try
{
const Derived &d = dynamic_cast<const Derived&>(b);
}
catch(bad_cast)
{
}
}
第二个是对const的转换:这里有个问题需要说一下,以前没注意到;非const变量默认为extern,但是const变量不是这样的,这就导致在多文件编程的时候出现问题了:
对于非constb变量
//other.c
int a = 10;
//main.c
//要是想调用a 必须声明extern
extern int a;
对于const变量来说就不可以了,就必须是:
//other.c
extern const int a = 10;
//main.c
//要是想调用a 必须声明extern
extern const int a;
现在说一下const_cast这个函数把,他的作用是将表达式中的const的性质去掉,例如
const int b = 1;
int *c = const_cast<int *>(&b);
*c = 10;
cout<<b<<endl;
cout<<*c<<endl;
虽然调用了这个函数后,可以直接编译通过,但是结果并不是我们想要的结果,结果是b=1,然后*c=10;
但是下面有做了一个:
class T
{
public:
int c;
T(int i) : c(i)
{}
};
const T s(1);
int *f = const_cast<int*>(&s.c);
*f = 10;
cout<<s.c<<endl;//发现s.c的值被改变了
如果是这样呢?
const T s(1);
T *t = const_cast<T *>(&s);
t->c = 10;
cout<<s.c<<endl;//发现也被改变了
在网上也查了一些资料,让我感觉满意的答案是const可以把变量真正声明为常量,只是对于内置的数据类型来说的,而用户自己定义的数据类型是不可以的;
昨天在论坛上提了这个问题,才发现我没有理解这个const_cast的真正用途,这个的真正用途是:把一些原本不是const的变量,由于某些原因导致变成了const类型的那些变量,恢复成非const类型。例如使用了一个const引用指向了一个本来不是const的对象.结果写了一些代码之后发现它实际上需要被修改. 这在平时的工作中不会遇到因为你可以直接把const引用修改成非const的,但C++中可能的情况太多,尤其考虑到很多复用的时候,有时还是会出现本不该是const的对象被const引用了这种情况.尤其是使用模板,比较复杂的情况.这才是const_cast的意义所在.
想了解const_cast使用中可能出现的未定义行为,可参考如下代码:
int main()
{
const int k=10;
int& x=const_cast<int>(k);
x=11;
return k;
}
这段代码中出现的就是典型的const_cast的未定义行为,return的值是完全不确定的,全看编译器
心情.而以下代码是正确的:
int main()
{
int k=10;
const int& ref=k;
int& x=const_cast<int>(ref);
x=11;
return k;
}
int a = 10;
void function(const int *pa)
{
如果确定进来的pa之前确实是一个变量,那么转换掉常量属性是安全的
}
第三个是static_cast函数:这个隐式执行的任何类型转换都可以,但是也是有限制的;它也有功能上限制。例如,你不能用static_cast象用C风格的类型转换一样把struct转换成int类型或者把double类型转换成指针类型,另外,static_cast不能从表达式中去除const属性,因为另一个新的类型转换操作符const_cast有这样的功能。
最后一个是reinterpret_cast:这个是进行操作数的位模式提供较低层次的重新解释
例如:
int a = 10;
int *pint = &a;
char *pchar = reinterpret_cast<char*>(pint);