在示例代码中,调用message()
永远不会影响该类的内容,因此我希望该方法为const
。但我不希望返回值也为const
,因此使用const_cast
如下安全吗?还是有更好的解决方案?
编辑:抱歉..所以n_
是一个指针!
EDIT2:我终于设法正确地重新产生了问题。如果n_
是int n[100]
中的数组,该怎么办?然后我看到没有const_cast
的问题。
class A
{
private:
int n_[10];
public:
/* ... */
int* n() const
{
return const_cast<int*>(n_);
}
};
答案 0 :(得分:7)
返回类型(不是引用)将生成您要返回的对象的副本。因此无需投射,可以在不影响原件的情况下更改副本。如果删除const_cast
,则代码将完全编译。
编辑:根据问题的最新修改,我会说这是对const_cast
的滥用。 C ++遵循的原则是const
成员函数不仅不应对对象本身进行任何更改,而且不应返回可用于在函数外部进行更改的任何内容。通过将非const指针返回到成员变量,您违反了这一原则。
答案 1 :(得分:5)
不,这不是const_cast
的有效用法。
您的函数未修改数组,但它授予将数组修改为调用者的权限。因此,它应该拥有这些权利。您无法让某人访问您自己无法访问的内容。因此该方法不应该是const,因此不需要const cast。
您可能还需要函数的const版本,它返回const int*
。这与例如std::vector::operator[]
的原理相同。即使操作符不修改向量,它也会授予访问权限以修改向量,因此它不是const函数。 (但是还有一个const重载版本,它返回一个const引用,因此不授予修改向量的权利)
答案 2 :(得分:0)
您可以返回n_
,因为它是
int n() const
{
return n_;
}
答案 3 :(得分:0)
无需使用演员阵容。在该函数中,this->n_
是一个const
指针,它不指向const int
。
int* n() const
{
// No need for a cast.
return n_;
}
从const int*
函数返回const
更有意义。你不想要这样的东西:
const A a;
a.n()[0] = 10;
这颠覆了对象的const
- ness。您可以使用以下命令来阻止:
const int* n() const
{
// No need for a cast either.
return n_;
}
答案 4 :(得分:0)
一般来说,将T const
投放到T
并const_cast<>
几乎总是不必要的。这是因为常量对象被转换为非常量临时对象,这可以在没有强制转换的情况下安全地完成。
int const n; // n is a constant int
int x = n; // perfectly safe
即使T
是指针类型,也是如此。
int * const n; // n is a constant pointer to an int
int * x = n; // perfectly safe
但是,如果将const
关键字移到前面,它不再使指针类型保持不变,而是指向常量的类型。因此,对于我们上面的例子:
const int * n; // n is a pointer to a constant int
int * x = n // error, x is a pointer to an int
您可以看到x
指向的内容与n
指向的内容不同,因此初始化将失败。在这种情况下,初始化需要const_cast<>
:
int * x = const_cast<int *>(n);
// cast away the const-ness that n is pointing to
如果您知道n
实际上是可修改的(如果指针指向实际的只读内存可能不是这样),或者如果您知道x
的用户,则应该这样做实际上不会尝试修改n
指向的内容。
对于您的示例,您似乎相信您的const
方法应返回指向对象所持数据的指针,以便调用者可以修改数据。也就是说,由于n()
方法被声明为const
,这意味着被访问对象的内容应该被认为是常量。因此,n_
是一个常量int
的数组,它将衰减为指向常量int
的指针,但是您想要返回指向int
的指针。
如果您希望n_
可以修改,无论该对象是否被视为常量,您都可以使用mutable
声明该意图。即使包含的对象为n_
,这也会使const
被视为非常量,因此不需要const_cast
。
class A
{
private:
mutable int n_[10];
public:
/* ... */
int* n() const
{
return n_;
}
};