C ++无法从' const char *'转换参数1到#char;'

时间:2016-01-27 19:30:17

标签: c++

我根本不是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 *'

3 个答案:

答案 0 :(得分:2)

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保留了副本,那么您就是安全的,但现在您可以获得额外副本的效果。

可能需要对std::string和任何类angular.module("ISG").directive('isgEditingFundDirective', function () { var ctrl = null; var isgEditingFundDirectiveController = function () { ctrl = this; // Getting a reference to the controller so it can be used in the link function. Is there a better way to do this? this.cancel = function () { // Undo the edit ctrl.fund = null; }; this.save = function () { // Save back to the original model angular.copy(ctrl.shadow, ctrl.fund); // Set to null because we aren't editing anymore ctrl.fund = null; } } var isgEditingFundDirectiveLink = function (scope, element, attrs) { // need link so we can undo an edit scope.$watch(ctrl.fund, function (orig, updated) { // Trying to watch the fund property in the controller so I can create a copy for undo later. // This never fires with a real value angular.copy(ctrl.fund, ctrl.shadow); }); } return { restrict: "E", controllerAs: 'editFundCtrl', templateUrl: "/angular/editfund", bindToController: { fund: "=fund" }, controller: isgEditingFundDirectiveController, link: isgEditingFundDirectiveLink }; }); 实例化进行修改。

3。大规模撕裂

使用现代技术和Editing fund Name: <input ng-model="editFundCtrl.shadow.FundName"/> <button ng-click="editFundCtrl.cancel()">Cancel</button> <button ng-click="editFundCtrl.save()">Save</button> <pre>{{editFundCtrl.fund}}</pre> 重写程序。您遇到的错误表明某人对其内存使用并不十分谨慎,并且可能还有其他时间的炸弹等待关闭。

这超出了Stack Overflow的范围。

答案 1 :(得分:0)

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

答案 2 :(得分:-3)

如果你真的必须这样做,你可以使用const_cast&lt;&gt;运营商。这是一个例子:

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