C ++不推荐将字符串常量转换为'char *'

时间:2009-10-06 08:45:51

标签: c++ string explicit-constructor

我有一个private char str[256];

的课程

为此,我有一个显式的构造函数:

explicit myClass(const char *func)
{
    strcpy(str,func);
}

我称之为:

myClass obj("example");

当我编译它时,我收到以下警告:

  

不推荐将字符串常量转换为'char *'

为什么会这样?

10 个答案:

答案 0 :(得分:140)

警告:

  

不推荐将字符串常量转换为'char *'

是因为你在某处(不是在你发布的代码中)做了类似的事情:

void foo(char* str);
foo("hello");

问题是您正在尝试将字符串文字(类型为const char[])转换为char*

您可以将const char[]转换为const char*,因为数组会衰减到指针,但您正在做的是将可变变量设为常量。

这种转换可能允许C兼容,只是给你提到警告。

答案 1 :(得分:81)

正如answer no. 2 by fnieto - Fernando Nieto明确而正确地描述了这个警告是因为您正在代码中的某个地方(而不是在您发布的代码中),如下所示:

void foo(char* str);
foo("hello");

但是,如果您想保持代码免提警告,那么只需对代码进行相应的更改:

void foo(char* str);
foo((char *)"hello");

即,只需将string常量强制转换为(char *)

答案 2 :(得分:30)

有3个解决方案:

解决方案1:

const char *x = "foo bar";

解决方案2:

char *x = (char *)"foo bar";

解决方案3:

char* x = (char*) malloc(strlen("foo bar")+1); // +1 for the terminator
strcpy(x,"foo bar");

也可以使用数组代替指针,因为数组已经是常量指针。

答案 3 :(得分:3)

实际上,字符串常量文字既不是const char *也不是char *而是char []。它很奇怪,但在c ++规范中写下来;如果修改它,则行为未定义,因为编译器可能将其存储在代码段中。

答案 4 :(得分:1)

我通过在代码的开头添加此宏来解决此问题。或者将其添加到<iostream>,呵呵。

 #define C_TEXT( text ) ((char*)std::string( text ).c_str())

答案 5 :(得分:1)

也许您可以尝试以下方法:

void foo(const char* str) 
{
    // Do something
}

foo("Hello")

对我有用

答案 6 :(得分:1)

此问题的原因(比其他人解释的char* str = "some string"问题更难发现)是在使用constexpr时。

constexpr char* str = "some string";

似乎它的行为类似于const char* str,因此不会引起警告,因为它发生在char*之前,但它的行为却像char* const str

详细信息

常量指针和指向常量的指针。 const char* strchar* const str之间的区别可以解释如下。

  1. const char* str:声明str为指向const char的指针。这意味着该指针指向的数据是恒定的。可以修改指针,但是任何试图修改数据的尝试都会引发编译错误。
    1. str++ ;有效。我们正在修改指针,而不是指向的数据。
    2. *str = 'a';无效。我们正在尝试修改所指向的数据。
  2. char* const str:声明str为指向char的const指针。这意味着该点现在是恒定的,但是所指向的数据也不是恒定的。指针不能被修改,但是我们可以使用指针来修改数据。
    1. str++ ;无效。我们正在尝试修改指针变量,它是一个常量。
    2. *str = 'a';有效。我们正在尝试修改所指向的数据。在我们的情况下,这不会导致编译错误,但会导致 运行时错误 ,因为该字符串很可能会进入已编译二进制文件的只读部分。如果我们已经动态分配了内存,那么该语句就有意义。 char* const str = new char[5];
  3. const char* const str:声明str为指向const char的const指针。在这种情况下,我们既不能修改指针,也不能修改指向的数据。
    1. str++ ;无效。我们正在尝试修改指针变量,它是一个常量。
    2. *str = 'a';无效。我们正在尝试修改此指针指向的数据,该数据也是恒定的。

在我的情况下,问题是我期望constexpr char* str的行为像const char* str,而不是char* const str,因为从视觉上看,它更接近前者。

此外,为constexpr char* str = "some string"生成的警告与char* str = "some string"略有不同。

  1. constexpr char* str = "some string"的编译器警告:ISO C++11 does not allow conversion from string literal to 'char *const'
  2. char* str = "some string"的编译器警告:ISO C++11 does not allow conversion from string literal to 'char *'

提示

您可以使用C gibberish ↔ English converterC声明转换为易于理解的英语语句,反之亦然。这是仅C的工具,因此将不支持C++专有的功能(例如constexpr)。

答案 7 :(得分:0)

我也遇到了同样的问题。我简单的做法就是添加const char *而不是char *。问题解决了。正如其他人在上面提到的,这是一个兼容的错误。 C将字符串视为char数组,而C ++将它们视为const char数组。

答案 8 :(得分:0)

为了它的价值,我发现这个简单的包装类有助于将C ++字符串转换为char *

class StringWrapper {
    std::vector<char> vec;
public:
    StringWrapper(const std::string &str) : vec(str.begin(), str.end()) {
    }

    char *getChars() {
        return &vec[0];
    }
};

答案 9 :(得分:-1)

下面说明了解决方案,将字符串分配给变量指向常量char数组的指针(字符串是指向常量char数组的常量指针 - 加上长度信息):

#include <iostream>

void Swap(const char * & left, const char * & right) {
    const char *const temp = left;
    left = right;
    right = temp;
}

int main() {
    const char * x = "Hello"; // These works because you are making a variable
    const char * y = "World"; // pointer to a constant string
    std::cout << "x = " << x << ", y = " << y << '\n';
    Swap(x, y);
    std::cout << "x = " << x << ", y = " << y << '\n';
}