C++表达式易错知识点

来源:互联网 发布:软件验收报告模板 编辑:程序博客网 时间:2024/06/08 07:54

求值顺序

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

  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.  }  
原创粉丝点击