当前位置:  开发笔记 > 编程语言 > 正文

const_cast安全吗?

如何解决《const_cast安全吗?》经验,为你挑选了6个好方法。

我找不到太多的信息const_cast.我能找到的唯一信息(在Stack Overflow上)是:

const_cast<>()用于添加/删除变量的常量(岬)(或挥发性岬).

这让我很紧张.可能const_cast会导致意外行为?如果是这样,什么?

或者,什么时候可以使用const_cast



1> Adam Rosenfi..:

const_cast只有在您投射最初非变量的变量时才是安全的const.例如,如果你有一个带a参数的函数const char *,并传入一个可修改的函数,那么该参数char *可以安全地const_cast返回char *并修改它.但是,如果原始变量实际上是const,那么使用const_cast将导致未定义的行为.

void func(const char *param, size_t sz, bool modify)
{
    if(modify)
        strncpy(const_cast(param), sz, "new string");
    printf("param: %s\n", param);
}

...

char buffer[16];
const char *unmodifiable = "string constant";
func(buffer, sizeof(buffer), true);  // OK
func(unmodifiable, strlen(unmodifiable), false); // OK
func(unmodifiable, strlen(unmodifiable), true);  // UNDEFINED BEHAVIOR


@Alexey Malistov:不."对象"是指内存中占用的实际存储区域(§1.7).对非const对象进行const引用不会使对象成为常量.只有在const**引用**参数(*not*a const pointer parameter)的情况下才允许编译器静默地复制(§5.2.2/ 5); 这不是这里的情况.
@Alexey:原始变量是关于指向或引用的内容.您可以对非const对象进行const引用,因此,将其转换为可写引用是明确定义的行为,因为引用的对象实际上不是const.
这不是真的.C++标准.`§7.1.5.1/ 4说除了可以修改任何声明可变的类成员(7.1.1),任何在其生命周期内修改const对象的尝试(3.8)都会导致未定义的行为.**任何尝试**!没有关于原始变量的文字.
_"但是,如果原始变量实际上是const,那么使用const_cast将导致未定义的行为"_此语句为false.
使用`const_cast`从最初声明为`const`的东西中删除`const`是*不是*UB.但它实际上是尝试写入该对象的*UB.只要你刚读完就好了,`const_cast`本身不会导致UB.这是一个可怕的想法,但它本身并不是UB.
@DarkFalcon看到这句话:`只有在const引用参数(不是const指针参数)的情况下才允许编译器从他的注释中默默地复制(第5.2.2/5节).
文字是唯一最初声明为const的数据吗?

2> Fred Larson..:

我可以想到const_cast安全且有用的两种情况(可能还有其他有效的情况).

一种是当你有一个const实例,引用或指针,并且你想要将指针或引用传递给不是const-correct的API,但是你肯定不会修改该对象.您可以const_cast指针并将其传递给API,相信它不会真正改变任何东西.例如:

void log(char* text);   // Won't change text -- just const-incorrect

void my_func(const std::string& message)
{
    log(const_cast(&message.c_str()));
}

另一种情况是,如果您使用的是未实现'mutable'的旧编译器,并且您希望创建一个逻辑上为const但不是按位const的类.您可以在const方法中const_cast"this"并修改类的成员.

class MyClass
{
    char cached_data[10000]; // should be mutable
    bool cache_dirty;        // should also be mutable

  public:

    char getData(int index) const
    {
        if (cache_dirty)
        {
          MyClass* thisptr = const_cast(this);
          update_cache(thisptr->cached_data);
        }
        return cached_data[index];
    }
};


从问题:"或者,什么时候可以使用const_cast?"

3> Rob Kennedy..:

我发现很难相信这是你能找到的关于const_cast 的唯一信息.引用第二个Google热门话题:

如果抛弃已显式声明为const的对象的常量,并尝试修改它,则结果是未定义的.

但是,如果丢弃未明确声明为const的对象的常量,则可以安全地修改它.



4> Johannes Sch..:

亚当说的话.另一个const_cast可以帮助的例子:

struct sample {
    T& getT() { 
        return const_cast(static_cast(this)->getT()); 
    }

    const T& getT() const { 
       /* possibly much code here */
       return t; 
    }

    T t;
};

我们首先将const添加到类型this点,然后我们调用const版本getT,然后我们从返回类型中删除const,这是有效的,因为t必须是非const(否则,非const版本getT不能有被称为).如果您有一个大型函数体并且想要避免冗余代码,这可能非常有用.


我宁愿使用static强制转换来添加constness:static_cast <const sample *>(this)。当我阅读const_cast时,它意味着代码正在做潜在危险的事情,因此我尝试避免在可能的情况下使用它。
我会来回询问`const_cast`或`static_cast`是否更好.`const_cast`只能做你想要的:更改cv限定符.`static_cast`可以'静默'执行你不想要的其他操作.但是,第一次演员是完全安全的,`static_cast`往往比`const_cast`更安全.我认为这是'const_cast`更好地传达你的意图的情况,但是`static_cast`可以更好地传达你行动的安全性.

5> JohnMcG..:

简短的回答是不,这不安全.

答案很长,如果你知道足够使用它,那么它应该是安全的.

当你在施法时,你基本上说的是,"我知道编译器不知道的东西." 在const_cast的情况下,你所说的是,"即使这个方法接受一个非const引用或指针,我知道它不会改变我传递它的参数."

因此,如果您确实知道在使用演员表时您声称知道的内容,那么可以使用它.



6> Matt Cruiksh..:

如果你开始修改编译器认为是const的东西,你就会破坏线程安全的任何机会.


Const肯定是使代码线程安全的有用工具,但它没有保证(除了编译时常量).两个例子:一个const对象可能有可变成员,并且有一个指向对象的const指针没有说明对象本身是否可以改变.
推荐阅读
手机用户2502851955
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有