C++表达式易错知识点

求值顺序

对于那些没有指定执行顺序的运算符来说,如果表达式指向并修改了同一个对象,将会引发错误并产生未定义的行为:

  int i=0;
  cout<<i<<"   "<<++i<<endl;
  //我们无法推断输出的值,可能是两个1,也可能是0  1
  //所以上述写法是一种错误!

再举两个例子,都是左右两边都用到了同一个变量,但改变了该变量的值:

*beg = toupper(*beg++);  //error! undefined behavior!

vec[i++] <= vec[i];  error! undefined behavior!

隐式类型转换

  • 数组转换成指针
    在大多数用到数组的表达式中,数组自动转换成指向数组首元素的指针:
int ia[10];  
int *ip = ia;  //ia转换成指向数组首元素的指针

当数组被用作decltype关键字的参数,或者作为取地址符(&)、sizeof及typeid等运算符的运算对象时,上述转换不会发生。

强制转换

  • static_cast
    static_cast,这种强制转换只会在编译时检查。 如果编译器检测到您尝试强制转换完全不兼容的类型,则static_cast会返回错误。 您还可以使用它在基类指针和派生类指针之间强制转换,但是,编译器在无法分辨此类转换在运行时是否是安全的。
double d = 1.58947;  
int i = d;  // warning C4244 possible loss of data  
int j = static_cast<int>(d);       // No warning.  
string s = static_cast<string>(d); // Error C2440:cannot convert from  
                                   // double to std:string  

// No error but not necessarily safe.  
Base* b = new Base();  
Derived* d2 = static_cast<Derived*>(b);  
  • dynamic_cast
    为了安全,dynamic_cast在运行时检查基类指针和派生类指针之间的强制转换。 dynamic_cast 是比 static_cast 更安全的强制类型转换,但运行时检查会带来一些开销。
Base* b = new Base();  

// Run-time check to determine whether b is actually a Derived*  
Derived* d3 = dynamic_cast<Derived*>(b);  

// If b was originally a Derived*, then d3 is a valid pointer.  
if(d3)  
{  
   // Safe to call Derived method.  
   cout << d3->DoSomethingMore() << endl;  
}  
else  
{  
   // Run-time check failed.  
   cout << "d3 is null" << endl;  
}  

//Output: d3 is null;  
  • const_cast
    const_cast转换为 const 的变量,或者将非 const 变量转换为 const。 通过使用这个操作符强制转换 const 就像使用C样式转换一样容易出错,不同之处在于使用 const_cast 不太可能意外地执行转换。 有时候你只能强制转换 const 的变量,例如,传递 const 变量到一个非 const 参数的函数中。 下面的示例演示如何执行此操作。
void Func(double& d) { ... }  
void ConstCast()  
{  
   const double pi = 3.14;  
   Func(const_cast<double&>(pi)); //No error.  
}  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值