我根本不是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 *'
答案 0 :(得分:2)
name
是一个常量c风格的字符串。它承诺函数的调用者不会在MessageGroup
构造函数内或MessageGroup
调用的任何函数中修改所提供的字符串。
_strupr(name) is going to convert
以大写字母命名,违反了无修改承诺。这是一件坏事,甚至可能是不可能的,因为存储区域保存名称可能不可写,并产生错误。也许在过去它只会产生警告并被忽略。不能使用我的Visual C 6及其默认设置,或者项目设置应该默认设置已更改为静音警告,所以我不确定是否有人甚至看到过警告。
问题的解决方案是:
MessageGroup
以删除const
MessageGroup::MessageGroup(char *name, WordCollection *words)
这可能会破坏使用MessageGroup
的其他代码片段并依赖于未更改的名称。我只是建议它,因为它很容易尝试。如果它炸毁了所有东西,请将const
放回去继续前进。
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
};
});
实例化进行修改。
使用现代技术和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.