c ++ - const_cast安全吗?

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

const_cast用于添加/删除变量的const(ness)(或volatile-ness)。

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

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

Mag Roader asked 2019-09-11T02:01:51Z
7个解决方案
86 votes

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

void func(const char *param, size_t sz, bool modify)
{
    if(modify)
        strncpy(const_cast<char *>(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
Adam Rosenfield answered 2019-09-11T02:02:07Z
34 votes

我可以想到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<char*>(&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<MyClass*>(this);
          update_cache(thisptr->cached_data);
        }
        return cached_data[index];
    }
};
Fred Larson answered 2019-09-11T02:02:47Z
22 votes

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

如果你抛弃了一个常数   已经明确的对象   声明为const,并尝试   修改它,结果是未定义的。

但是,如果你抛弃了   没有的对象的常量   已被明确声明为const,你   可以安全地修改它。

Rob Kennedy answered 2019-09-11T02:03:25Z
10 votes

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

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

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

    T t;
};

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

Johannes Schaub - litb answered 2019-09-11T02:03:59Z
8 votes

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

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

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

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

JohnMcG answered 2019-09-11T02:04:46Z
5 votes

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

Matt Cruikshank answered 2019-09-11T02:05:13Z
-1 votes
#include <iostream>
using namespace std;

void f(int* p) {
  cout << *p << endl;
}

int main(void) {
  const int a = 10;
  const int* b = &a;

  // Function f() expects int*, not const int*
  //   f(b);
  int* c = const_cast<int*>(b);
  f(c);

  // Lvalue is const
  //  *b = 20;

  // Undefined behavior
  //  *c = 30;

  int a1 = 40;
  const int* b1 = &a1;
  int* c1 = const_cast<int*>(b1);

  // Integer a1, the object referred to by c1, has
  // not been declared const
  *c1 = 50;

  return 0;
}

来源:[http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fkeyword_const_cast.htm]

Mr.Angel answered 2019-09-11T02:05:40Z
translate from https://stackoverflow.com:/questions/357600/is-const-cast-safe