error: ISO C++ forbids converting a string constant to ‘char*’
error: ISO C++ forbids converting a string constant to ‘char*’
我正在尝试 运行 以下代码,摘自 Balagurusamy 的“C++ 面向对象编程”(第 8 版):
#include <iostream>
#include <cstring>
using namespace std;
class String
{
char *name;
int length;
public:
String()
{
length = 0;
name = new char[length+1];
}
String(char *s)
{
length = strlen(s);
name = new char[length+1];
strcpy(name,s);
}
void display(void)
{cout<<name<<"\n";}
void join(String &a, String &b);
};
void String :: join(String &a, String &b)
{
length = a.length + b.length;
delete name;
name = new char[length+1];
strcpy(name, a.name);
strcat(name, b.name);
};
int main()
{
char *first = "Joseph ";
String name1(first), name2("Louis"), name3("Lagrange"), s1,s2;
s1.join(name1, name2);
s2.join(s1,name3);
name1.display();
name2.display();
name3.display();
s1.display();
s2.display();
return 0;
}
当我用g++编译时,我运行进入以下日志:
g++ -Wall -Werror -Wextra constructors_with_new.cpp -o constructors_with_new.o
constructors_with_new.cpp: In function ‘int main()’:
constructors_with_new.cpp:45:15: error: ISO C++ forbids converting a string constant to ‘char*’ [-Werror=write-strings]
45 | char *first = "Joseph ";
| ^~~~~~~~~
constructors_with_new.cpp:47:28: error: ISO C++ forbids converting a string constant to ‘char*’ [-Werror=write-strings]
47 | String name1(first), name2("Louis"), name3("Lagrange"), s1,s2;
| ^~~~~~~
constructors_with_new.cpp:47:44: error: ISO C++ forbids converting a string constant to ‘char*’ [-Werror=write-strings]
47 | String name1(first), name2("Louis"), name3("Lagrange"), s1,s2;
| ^~~~~~~~~~
cc1plus: all warnings being treated as errors
然后我找到了下面的答案
为什么从字符串常量到'char*'的转换在C中有效但在C++中无效
为了让它工作,我修改了上面的代码
- 在第二个构造函数中接收指向
const
字符的指针 (String(char const *s)
)
- 在
main()
中,通过将名字“Joseph”的初始化从 char * first
更改为 char const * first
,正如 Jeremy Coffin 在对提供的 link
这样编译没有问题输出如下
Joseph
Louis
Lagrange
Joseph Louis
Joseph Louis Lagrange
我想知道这是否是解决此问题的最佳方法,或者您是否推荐一种不同的方法(也许是另一种不需要输入指向类型 const
的指针的方法 char
).
最佳,
斯特凡诺
C++ 中的字符串文字默认为 const char*。这就是为什么您在尝试将 const char* 分配给 char* 时看到这些警告的原因。
您可以通过放弃 char* 的常量性来简单地删除这些警告。您可以使用 const_cast<char*>
来实现
例如:
char *first = const_cast<char*>("Joseph ");
String name1(first), name2(const_cast<char*>("Louis")), name3(const_cast<char*>("Lagrange")), s1,s2;
这应该会删除您的警告。
编辑:这不是最好的建议。我的回答只是为了解释如何丢弃字符串文字的 const-ness 而绝不会提升它。字符串常量的存在是有原因的。
如注释所示,您需要使用 const char*
,而不是 char*
。看来这本书已经严重过时了。
在 C++ 中,字符串文字的类型为 const char[N]
,其中 N
是文字中的字符数加上终止 '[=14=]'
.
的字符数
我能够编译您的代码,并且 运行 通过进行以下更改:
- 将
String
的构造函数从
更改为
String(char *s)
至
String(const char *s)
- 将
first
的声明从
更改为
char *first = "Joseph ";
至
const char *first = "Joseph ";
- 删除
String::join
末尾的多余分号。
另外,如果缩进得当,代码会更清晰。
我正在尝试 运行 以下代码,摘自 Balagurusamy 的“C++ 面向对象编程”(第 8 版):
#include <iostream>
#include <cstring>
using namespace std;
class String
{
char *name;
int length;
public:
String()
{
length = 0;
name = new char[length+1];
}
String(char *s)
{
length = strlen(s);
name = new char[length+1];
strcpy(name,s);
}
void display(void)
{cout<<name<<"\n";}
void join(String &a, String &b);
};
void String :: join(String &a, String &b)
{
length = a.length + b.length;
delete name;
name = new char[length+1];
strcpy(name, a.name);
strcat(name, b.name);
};
int main()
{
char *first = "Joseph ";
String name1(first), name2("Louis"), name3("Lagrange"), s1,s2;
s1.join(name1, name2);
s2.join(s1,name3);
name1.display();
name2.display();
name3.display();
s1.display();
s2.display();
return 0;
}
当我用g++编译时,我运行进入以下日志:
g++ -Wall -Werror -Wextra constructors_with_new.cpp -o constructors_with_new.o
constructors_with_new.cpp: In function ‘int main()’:
constructors_with_new.cpp:45:15: error: ISO C++ forbids converting a string constant to ‘char*’ [-Werror=write-strings]
45 | char *first = "Joseph ";
| ^~~~~~~~~
constructors_with_new.cpp:47:28: error: ISO C++ forbids converting a string constant to ‘char*’ [-Werror=write-strings]
47 | String name1(first), name2("Louis"), name3("Lagrange"), s1,s2;
| ^~~~~~~
constructors_with_new.cpp:47:44: error: ISO C++ forbids converting a string constant to ‘char*’ [-Werror=write-strings]
47 | String name1(first), name2("Louis"), name3("Lagrange"), s1,s2;
| ^~~~~~~~~~
cc1plus: all warnings being treated as errors
然后我找到了下面的答案
为什么从字符串常量到'char*'的转换在C中有效但在C++中无效
为了让它工作,我修改了上面的代码
- 在第二个构造函数中接收指向
const
字符的指针 (String(char const *s)
) - 在
main()
中,通过将名字“Joseph”的初始化从char * first
更改为char const * first
,正如 Jeremy Coffin 在对提供的 link
这样编译没有问题输出如下
Joseph
Louis
Lagrange
Joseph Louis
Joseph Louis Lagrange
我想知道这是否是解决此问题的最佳方法,或者您是否推荐一种不同的方法(也许是另一种不需要输入指向类型 const
的指针的方法 char
).
最佳,
斯特凡诺
C++ 中的字符串文字默认为 const char*。这就是为什么您在尝试将 const char* 分配给 char* 时看到这些警告的原因。
您可以通过放弃 char* 的常量性来简单地删除这些警告。您可以使用 const_cast<char*>
例如:
char *first = const_cast<char*>("Joseph ");
String name1(first), name2(const_cast<char*>("Louis")), name3(const_cast<char*>("Lagrange")), s1,s2;
这应该会删除您的警告。
编辑:这不是最好的建议。我的回答只是为了解释如何丢弃字符串文字的 const-ness 而绝不会提升它。字符串常量的存在是有原因的。
如注释所示,您需要使用 const char*
,而不是 char*
。看来这本书已经严重过时了。
在 C++ 中,字符串文字的类型为 const char[N]
,其中 N
是文字中的字符数加上终止 '[=14=]'
.
我能够编译您的代码,并且 运行 通过进行以下更改:
- 将
String
的构造函数从
更改为String(char *s)
至
String(const char *s)
- 将
first
的声明从
更改为char *first = "Joseph ";
至
const char *first = "Joseph ";
- 删除
String::join
末尾的多余分号。
另外,如果缩进得当,代码会更清晰。