C++ const_cast 安全吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/357600/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 14:54:02  来源:igfitidea点击:

Is const_cast safe?

c++castingconst-cast

提问by Mag Roader

I can't find much information on const_cast. The only info I could find (on Stack Overflow) is:

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

The const_cast<>()is used to add/remove const(ness) (or volatile-ness) of a variable.

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

This makes me nervous. Could using a const_castcause unexpected behavior? If so, what?

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

Alternatively, when is it okay to use const_cast?

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

采纳答案by Adam Rosenfield

const_castis safe only if you're casting a variable that was originally non-const. For example, if you have a function that takes a parameter of a const char *, and you pass in a modifiable char *, it's safe to const_castthat parameter back to a char *and modify it. However, if the original variable was in fact const, then using const_castwill result in undefined behavior.

const_cast仅当您正在强制转换最初为非 的变量时才是安全的const。例如,如果您有一个接受 a 参数的函数const char *,并且您传入了一个可修改的char *,那么const_cast将该参数返回给 achar *并对其进行修改是安全的。但是,如果原始变量实际上是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

回答by Fred Larson

I can think of two situations where const_cast is safe and useful (there may be other valid cases).

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

One is when you have a const instance, reference, or pointer, and you want to pass a pointer or reference to an API that is not const-correct, but that you're CERTAIN won't modify the object. You can const_cast the pointer and pass it to the API, trusting that it won't really change anything. For example:

一种情况是,当您有一个 const 实例、引用或指针时,您想将一个指针或引用传递给一个不正确的 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()));
}

The other is if you're using an older compiler that doesn't implement 'mutable', and you want to create a class that is logically const but not bitwise const. You can const_cast 'this' within a const method and modify members of your class.

另一种情况是,如果您使用的是未实现“可变”的旧编译器,并且您想创建一个逻辑上为常量但不是按位常量的类。您可以在 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];
    }
};

回答by Rob Kennedy

I find it hard to believe that that's the onlyinformation you could find about const_cast. Quoting from the second Google hit:

我很难相信这是你能找到的关于 const_cast的唯一信息。引自第二个谷歌热门

If you cast away the constness of an object that has been explicitly declared as const, and attempt to modify it, the results are undefined.

However, if you cast away the constness of an object that has not been explicitly declared as const, you can modify it safely.

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

但是,如果您抛弃了尚未显式声明为 const 的对象的常量性,则可以安全地修改它。

回答by Johannes Schaub - litb

What Adam says. Another example where const_cast can be helpful:

亚当说什么。另一个 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;
};

We first add const to the type thispoints to, then we call the const version of getT, and then we remove const from the return type, which is valid since tmust be non-const (otherwise, the non-const version of getTcouldn't have been called). This can be very useful if you got a large function body and you want to avoid redundant code.

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

回答by JohnMcG

The short answer is no, it's not safe.

简短的回答是否定的,它不安全。

The long answer is that if you know enough to use it, then it should be safe.

长的答案是,如果您知道足够多的知识来使用它,那么它应该是安全的。

When you're casting, what you are essentially saying is, "I know something the compiler doesn't know." In the case of const_cast, what you are saying is, "Even though this method takes in a non-const reference or pointer, I know that it won't change the parameter I pass it."

当您进行强制转换时,您实际上是在说:“我知道编译器不知道的事情。” 在 const_cast 的情况下,你说的是,“即使这个方法接受一个非常量引用或指针,我知道它不会改变我传递的参数。”

So if you do actually know what you are claiming to know in using the cast, then it's fine to use it.

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

回答by Matt Cruikshank

You're destroying any chance at thread-safety, if you start modifying things that the compiler thought were const.

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

回答by Mr.Angel

#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;
}

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

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