C ++ const_cast用法而不是C风格的强制转换

时间:2008-12-16 06:30:15

标签: c++ const-cast

为什么会出现以下情况?:

  const int i0 = 5;
//int       i1 = const_cast<int>(i0);       // compilation error
  int       i2 = (int)i0;                   // okay

  int       i3 = 5;
//const int i4 = const_cast<const int>(i3); // compilation error
  const int i5 = (const int)i3;             // okay

4 个答案:

答案 0 :(得分:20)

  const int i0 = 5;
//int       i1 = const_cast<int>(i0);       // compilation error
  int       i2 = (int)i0;                   // okay

  int       i3 = 5;
//const int i4 = const_cast<const int>(i3); // compilation error
  const int i5 = (const int)i3;             // okay

编译错误是由于你没有强制转换const / add const引起的。相反,你复制i0。对于该操作,根本不需要强制转换:

int i1 = i0;
const int i4 = i3;

您投射到的类型实际上应该是指针或引用。否则,使用const_cast没有意义,因为你可以直接复制它。例如,对于指针,您可以抛弃const,因为取消引用指针将产生const T*的另一种类型(产生const T)而不是T*(产生T })。对于引用,情况也是如此:T&将使用另一个指针类型而不是使用const T&来访问对象。现在您真正想要存档的内容:

  const int i0 = 5;
//int &     i1 = const_cast<int&>(i0);      // okay (but dangerous)
  int &     i2 = (int&)i0;                  // okay (but dangerous)

  int       i3 = 5;
//const int&i4 = const_cast<const int&>(i3); // ok now and valid!
  const int&i5 = (const int&)i3;             // okay too!

当你通过对非const的引用写入一个原始的const对象时,上面会导致未定义的行为(实际上,只是转换和读取它本身并不是未定义的行为。但是如果你要丢弃const ,你也可以写信给它,然后产生未定义的行为)

答案 1 :(得分:5)

这是一个错误,因为标准说它是不允许的。该标准列举了const_cast允许执行的转换类型,并且它不允许列表中没有的任何内容。它允许以下内容:

  • 指针
  • 参考
  • 会员三分

由于您的类型不属于任何类型,因此不允许使用。

从好的方面来看,您提供的示例并非需要 const_cast

答案 2 :(得分:0)

第一个错误。 const_cast只能用于指针或引用类型。 “int”既不是。这可能是也可能不是C ++标准(找不到好的参考)。但是某些实现就是这种情况,例如MS的C ++编译器。

第二个错误。 const_cast只能用于删除const或volatile限定符而不添加它。

参考:http://msdn.microsoft.com/en-us/library/bz6at95h(VS.80).aspx

答案 3 :(得分:0)

根据CPP Reference,结果必须是指针或引用。使用指针时,输入也必须是指针。对于引用,可以将变量作为输入,将引用作为输出。该页面显示:

任何类型T的

左值都可以转换为左值或右值引用 相同的T型,或多或少具有cv资格。同样,prvalue为 类类型或任何类型的xvalue可能会或多或少地转换为 cv合格的右值参考。

含义

/* lvalue can be converted to lvalue or rvalue references  */
int& test1 = const_cast<int&>(var);   // lvalue to l-ref; same works for class type
int&& test2 = const_cast<int&&>(var); // lvalue to r-ref; same works for class type
/* prvalues: restriction on built-in types to allow some compiler optimization */
//int&& test5 = const_cast<int&&>(1);            // prvalue of built-in not allowed
A&& test6 = const_cast<A&&>(A());                // prvalue of class type allowed
/* xvalue can be converted to rvalue references */
int&& test8 = const_cast<int&&>(std::move(var)); //xvalue of built-in
A&& test8 = const_cast<A&&>(std::move(A()));     // xvalue of class