繁体   English   中英

这是const_cast的有效用法吗?

[英]Is this a valid use of const_cast?

在示例代码中,调用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_);
    }
};

返回类型(不是引用)将复制您要返回的对象。 因此,无需进行转换,可以在不影响原件的情况下更改副本。 如果删除const_cast ,代码将干净地编译。

编辑:根据对该问题的最新编辑,我会说这是const_cast的滥用。 C ++遵循的原理是, const成员函数不仅不应对对象本身进行任何更改,而且不应返回任何可用于在函数外部进行更改的内容。 通过返回指向成员变量的非常量指针,您违反了该原理。

不,这不是const_cast的有效使用。

您的功能不是修改数组,而是向调用者授予修改数组的权限。 因此,它本身应具有这些权利。 您无法授予某人访问您自己无权访问的内容的权限。 因此,该方法不应为const,因此不需要const cast。

您可能还需要该函数的const版本,该版本返回const int* 这与例如std::vector::operator[]原理相同。 即使运算符不修改向量,它也会授予访问权限以修改向量,因此它不是const函数。 (但是也有一个const重载版本,它返回const引用,因此没有授予修改向量的权利)

您可以按原样返回n_

int n() const
{
    return n_;
}

无需使用演员表。 在函数中, this->n_const指针,它并不指向const int

int* n() const
{
    // No need for a cast.
    return n_;
}

const函数返回const int*更有意义。 您不想要这样的东西:

const A a;
a.n()[0] = 10;

这颠覆了对象的const 您可以使用以下方法防止出现这种情况:

const int* n() const
{
    // No need for a cast either.
    return n_;
}

一般来说,铸造T constTconst_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声明该意图。 即使所包含的对象是const ,这也将n_视为非常量,因此不需要const_cast

class A
{
private:
    mutable int n_[10];

public:
    /* ... */

    int* n() const
    {
        return n_;
    }
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM