我有一堂课private char str[256];
为此我有一个显式的构造函数:
explicit myClass(const char *func)
{
strcpy(str,func);
}
我称之为:
myClass obj("example");
当我编译它时,我收到以下警告:
不推荐将字符串常量转换为 'char*'
为什么会这样?
我有一堂课private char str[256];
为此我有一个显式的构造函数:
explicit myClass(const char *func)
{
strcpy(str,func);
}
我称之为:
myClass obj("example");
当我编译它时,我收到以下警告:
不推荐将字符串常量转换为 'char*'
为什么会这样?
这是您在遇到如下情况时看到的错误消息:
char* pointer_to_nonconst = "string literal";
为什么?好吧,C 和 C++ 在字符串文字的类型上有所不同。在 C 中,类型是 char 数组,而在 C++ 中,类型是 char常量数组。在任何情况下,您都不允许更改字符串文字的字符,因此 C++ 中的 const 并不是真正的限制,而是更多的类型安全。出于安全原因,如果没有明确的强制转换,从const char*
to的转换char*
通常是不可能的。但是为了与 C 向后兼容,C++ 语言仍然允许将字符串文字分配给 achar*
并警告您不推荐使用此转换。
因此,为了 const 的正确性,您在程序中缺少一个或多个const
s。但是您向我们展示的代码不是问题,因为它没有进行这种已弃用的转换。警告一定来自其他地方。
警告:
不推荐将字符串常量转换为 'char*'
给出是因为您正在某处(而不是在您发布的代码中)执行以下操作:
void foo(char* str);
foo("hello");
问题是您正在尝试将字符串文字(类型为const char[]
)转换为char*
.
您可以将 a 转换为const char[]
,const char*
因为数组衰减到指针,但是您正在做的是使可变的常量。
这种转换可能是为了 C 兼容性而允许的,只是给你提到的警告。
作为答案没有。2 fnieto - Fernando Nieto清楚而正确地描述了发出此警告是因为您正在执行的代码中的某处(而不是您发布的代码中)类似于:
void foo(char* str);
foo("hello");
但是,如果您还想保持代码无警告,那么只需对代码进行相应的更改:
void foo(char* str);
foo((char *)"hello");
也就是说,只需将string
常量转换为(char *)
。
有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");
数组也可以用来代替指针,因为数组已经是一个常量指针。
这个问题的一个原因(这比char* str = "some string"
其他人解释的问题更难检测)是当您使用constexpr
.
constexpr char* str = "some string";
似乎它的行为类似于const char* str
,因此不会像之前那样引起警告,char*
而是表现为char* const str
。
常量指针,以及指向常量的指针。const char* str
和之间的区别char* const str
可以解释如下。
const char* str
: 将 str 声明为指向 const char 的指针。这意味着这个指针指向的数据是不变的。可以修改指针,但任何修改数据的尝试都会引发编译错误。
str++ ;
:有效。我们正在修改指针,而不是指向的数据。*str = 'a';
:无效。我们正在尝试修改指向的数据。char* const str
: 将 str 声明为指向 char 的 const 指针。这意味着该点现在是恒定的,但指向的数据也不是。指针无法修改,但我们可以使用指针修改数据。
str++ ;
:无效。我们正在尝试修改指针变量,它是一个常量。*str = 'a';
:有效。我们正在尝试修改指向的数据。在我们的例子中,这不会导致编译错误,但会导致运行时错误,因为字符串很可能会进入已编译二进制文件的只读部分。如果我们动态分配了内存,这个语句就有意义了,例如。char* const str = new char[5];
.const char* const str
: 将 str 声明为指向 const char 的 const 指针。在这种情况下,我们既不能修改指针,也不能修改指向的数据。
str++ ;
:无效。我们正在尝试修改指针变量,它是一个常量。*str = 'a';
:无效。我们试图修改这个指针指向的数据,它也是常量。就我而言,问题是我希望constexpr char* str
表现得像const char* str
,而不是char* const str
,因为在视觉上它似乎更接近前者。
此外,生成的警告constexpr char* str = "some string"
与char* str = "some string"
.
constexpr char* str = "some string"
:ISO C++11 does not allow conversion from string literal to 'char *const'
char* str = "some string"
: ISO C++11 does not allow conversion from string literal to 'char *'
。您可以使用C gibberish ↔ 英语转换器将C
声明转换为易于理解的英语语句,反之亦然。这是C
唯一的工具,因此不支持C++
.
事实上,字符串常量文字既不是 const char * 也不是 char*,而是 char[]。它很奇怪,但写在 c++ 规范中;如果您修改它,则行为未定义,因为编译器可能会将其存储在代码段中。
也许你可以试试这个:
void foo(const char* str)
{
// Do something
}
foo("Hello")
这个对我有用
我通过在代码开头的某个地方添加这个宏来解决这个问题。或者加进去<iostream>
,呵呵。
#define C_TEXT( text ) ((char*)std::string( text ).c_str())
我也遇到了同样的问题。而我所做的只是添加 const char* 而不是 char*。问题解决了。正如其他人在上面提到的那样,这是一个兼容错误。C 将字符串视为 char 数组,而 C++ 将它们视为 const char 数组。
对于它的价值,我发现这个简单的包装类有助于将 C++ 字符串转换为char *
:
class StringWrapper {
std::vector<char> vec;
public:
StringWrapper(const std::string &str) : vec(str.begin(), str.end()) {
}
char *getChars() {
return &vec[0];
}
};
下面说明了解决方案,将您的字符串分配给指向 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';
}