关于C++中 const_cast 的问题

10

所有人: 这段引用来自《Effective C++第三版》

const_cast通常用于去除对象的const属性。它是唯一可以这样做的C++类型转换。

我的问题是:const_cast能否给非const对象添加const属性? 实际上,我写了一个小程序试图证明我的想法。

class ConstTest
{
 public:

 void test() {
    printf("calling non-const version test const function \n");
}

 void test() const{
    printf("calling const version test const function \n");

} 

};
 int main(int argc,char* argv){
 ConstTest ct;
 const ConstTest cct;
 cct.test();
 const_cast<const ConstTest&>(ct).test();//it is wrong to write this statement without the '&',why

}

省略'&'会导致以下错误:
错误 C2440: 'const_cast' : 无法从 'ConstTest' 转换为 'const ConstTest'
这表明const_cast可以添加const属性,但似乎必须强制转换为对象引用,那么这个引用的神奇之处是什么呢?

为什么要使用const_cast添加const?只需将非const对象分配给const变量即可完成。我不知道为什么在你的情况下const引用起作用。 - Karel Petranek
2
假设一个成员函数有const和non-const覆盖:在不进行复制的情况下如何在non-const对象上调用const覆盖?(答案是static_cast,但对我来说为什么const_cast也不起作用并不明显) - Tyler McHenry
@Tyler:你可以使用static_cast将其转换为常量引用。 - Alexandre C.
1
@Alexandre 是的,我知道这是你的操作方法,但这个问题让我好奇 C++ 标准为什么选择不允许 const_cast 用于此目的,因为这种类型的转换的逻辑目的是更改变量的 const 特性。 - Tyler McHenry
4个回答

8
您不需要使用const_cast来添加const属性:
class C;
C c;
C const& const_c = c;

另一种方法需要使用 const_cast
const C const_c;
C& c = const_cast<C&>(const_c);

但如果您尝试在c上使用非const操作,行为将是未定义的。

顺便说一下,如果您不使用引用,将会复制对象:

C d = const_c; // Copies const_c

1
然而,有时添加const是一件有用的事情,因为它允许比添加额外(引用)变量更简洁的代码。请参见此页面的下半部分:http://books.google.de/books?id=mT7E5gDuW_4C&pg=PA188。请注意,正如[sharptooth正确指出的](https://dev59.com/tlDTa4cB1Zd3GeqPLr_U#3803545),它只能用于转换为`const` _reference_。 - sbi
为什么去除const_c的常量性是未定义的?如果它是内置类型,比如char、int、bool等,会怎样呢? - Tracy
行为不会未定义,除非您尝试使用非常量引用修改const对象。 - Steve Jessop

3

const_cast也可以用于添加const属性。

$5.2.11/3 - "For two pointer types T1 and T2 where

T1 is cv1 , 0 pointer to cv1 , 1 pointer to . . . cv1 ,n − 1 pointer to cv1 ,n T
and
T2 is cv2 , 0 pointer to cv2 , 1 pointer to . . . cv2 ,n − 1 pointer to cv2 ,n T

where T is any object type or the void type and where cv1 ,k and cv2 ,k may be different cv-qualifications, an rvalue of type T1 may be explicitly converted to the type T2 using a const_cast. The result of a pointer const_cast refers to the original object.

考虑:
int *t1 = NULL;  // T = int, cv1, 0 = none
int * const t2 = const_cast<int * const>(t1);   // T = int, cv2, 0 = const

根据上面的引用,上述内容是正确的,并且它为t添加了const属性。
但是正如Herb Sutter所说,大多数情况下可能不需要明确地执行此操作。

我已经阅读了相当多的书籍,但其中没有一本提到使用const_cast来向对象或对象引用添加const属性。然而,我遇到的是使用static_cast来实现同样的效果,这是由Scott Meyers在《Effective C++》中介绍的。哎呀,无法链接到Google图书。 - Tracy
@Tracy:请查看这个链接:http://lookdit.wordpress.com/2010/05/27/c-common-knowledge-by-stephen-c-dewherst/(查看第9项)。 - Chubsdad

2

const_cast只能用于指针和引用的转换,不能用于对象的转换。原因是:如果你有一个const对象,你不能将其变为非const,反之亦然——它已经是const了,你不能重新声明它。你只能通过指针或引用来尝试访问它,无论是否带有const。


1

const_cast 无法修改值的常量性,因此它返回一个对该值的常量引用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接