C++无法将参数 1 从"常量字符 *"转换为"字符 *"

C++ cannot convert parameter 1 from 'const char *' to 'char *'

本文关键字:字符 常量 转换 参数 C++      更新时间:2023-10-16

我根本不是一个C++开发人员,但正在执行将一些旧代码从Visual Studio 6升级到Visual Studio 2010的任务。 我从以下代码中收到错误。

MessageGroup::MessageGroup(const char *name, WordCollection *words) {
    _name.assign(_strupr(name));
    setWordCollection(words);
}

错误:

error C2664: '_strupr' : cannot convert parameter 1 from 'const char *' to 'char *'

name是一个常量的 c 样式字符串。它向函数的调用方承诺,提供的字符串不会在 MessageGroup 构造函数内部或由 MessageGroup 调用的任何函数修改。

_strupr(name) is going to convert 名称"改为大写,违反了不修改的承诺。这是一件坏事,甚至可能是不可能的,因为保存名称的内存区域可能不可写,并生成错误。也许在过去,它只生成警告并被忽略。不是在我的 Visual C 6 上,它是默认设置,或者项目设置应该默认设置已更改为静音警告,所以我不确定是否有人甚至看到过警告。

该问题的解决方案是:

1. 修改MessageGroup以删除const

MessageGroup::MessageGroup(char *name, WordCollection *words)

这可能会破坏无数其他使用MessageGroup的代码段,并指望名称传递不变。我只是建议这样做,因为它很容易尝试。如果它炸毁了所有东西,请把const放回去,然后继续前进。

2. 将name复制到可写的新内存缓冲区。

char * temp = new char[strlen(name)]; 
_name.assign(_strupr(temp));
delete temp; 

但是考虑一个智能指针,因为它会在发生坏事时自我管理内存。

std::unique_ptr<char[]> temp(new char[strlen(name)])
_name.assign(_strupr(temp.get));

这里的肮脏是我们不知道name的寿命。当你完成记忆时,谁负责delete temp的记忆?如果_name.assign只是复制指针而不是制作和保留数据的副本,则MessageGroup无法执行清理,因为_name将包含无效指针。如果_name保留副本,那么您是安全的,但现在您有一个额外的副本会影响性能。

可能需要修改_name.assign以及实例化的任何类_name

3. 可观的撕裂

用现代技术和std::string重写程序。您遇到的错误表明某人对他们的内存使用不是很小心,并且可能还有其他定时炸弹等待爆炸。

这超出了堆栈溢出的范围。

const类型不能作为接受它作为const的契约的一部分进行修改;这允许其他代码调用你的代码,而不必担心值被更改。但是,由于后续代码可能会导致修改,因此无法将 const 参数传递给接受非const版本的方法 - 在这种情况下,name.assign似乎会这样做,因此name.assign(_strupr(name));无效。

如果你真的必须这样做,你可以使用const_cast<>运算符。下面是示例:

const int j = 3; // j is declared const
nt* pj = const_cast<int*>(&j); // now content of pj can be modified.

这是链接: http://en.cppreference.com/w/cpp/language/const_cast