[英]Simple C++ function — Is this code “good”?
以下代码由为我的小组工作的顾问制作。 我不是一个C ++开发人员(虽然工作在很多语言中)但是想对以下代码有一些独立的意见。 这是在Visual Studio C ++ 6.0中。 我有一个直觉反应(显然不是一个很好的反应),但我想要那些来自经验丰富(甚至不是那么没有经验)的C ++开发人员的“直觉反应”。 提前致谢!
// Example call
strColHeader = insert_escape(strColHeader, ',', '\\'); //Get rid of the commas and make it an escape character
...略...
CString insert_escape ( CString originalString, char charFind, char charInsert ) {
bool continueLoop = true;
int currentInd = 0;
do {
int occurenceInd = originalString.Find(charFind, currentInd);
if(occurenceInd>0) {
originalString.Insert(occurenceInd, charInsert);
currentInd = occurenceInd + 2;
}
else {
continueLoop = false;
}
} while(continueLoop);
return(originalString);
}
哼。 我认为
CString strColHeader;
strColHeader.Replace(",", "\\,")
也会这样做。
我不喜欢代码,我倾向于从while循环中断,而不是有一个不必要的bool'continin'标志。 当他可以使用while (occurenceInd != 0)
作为他的循环控制变量而不是布尔值时,这会加倍。
增加计数器也依赖于“+2”,这似乎不能立即理解(不是一瞥),最后(最重要的)他似乎没有做评论。
中间有一个一个一个错误的错误:看看如果第一个字符是逗号会发生什么:“,abc,def,ghi”:我假设所需的输出是“\\, abc \\,def \\,ghi“,而是你得到原来的字符串:
int occurenceInd = originalString.Find(charFind, currentInd);
OccurrenceInd返回0,因为它在第一个字符处找到了charFind。
if(occurenceInd>0)
0不大于0,所以取else分支并返回原始字符串。 CString :: Find在找不到内容时返回-1,所以至少比较应该是:
if(occurrenceInd >= 0)
最好的方法是使用Replace函数,但如果你想手动完成,更好的实现可能看起来像这样:
CString insert_escape ( const CString &originalString, char charFind, char charInsert ) {
std::string escaped;
// Reserve enough space for each character to be escaped
escaped.reserve(originalString.GetLength() * 2);
for (int iOriginal = 0; iOriginal < originalString.GetLength(); ++iOriginal) {
if (originalString[iOriginal] == charFind)
escaped += charInsert;
escaped += originalString[iOriginal];
}
return CString(escaped.c_str());
}
已经提到了错误。 但是,他们认为任何人都可能遇到的问题很快就会被快速破解,而且还没有经过适当的测试,特别是如果他们不熟悉CString的话。
我更担心风格的东西,因为他们建议有人不熟悉C ++。 使用bool continueLoop只是简单的C ++。 它代表函数代码的三分之一,可以通过使用简单的if ... break构造来消除,使代码更容易在流程中遵循。
此外,变量名称“originalString”非常具有误导性。 因为它们是按值传递的,所以它不是原始字符串,而是它的副本! 然后他们无论如何都要修改字符串,因此它不再是与原始文本相同的对象或相同的文本字符串。 这种双重谎言暗示了混乱的思维模式。
CString有一个Replace()方法......(这是我的第一反应)
我看到了很多不好的代码,而且比这更糟糕。 但是,如果没有明显的理由,那么就不要使用内置功能。
我的直觉反应是: WTF 。 最初是如何格式化代码(有许多我不喜欢格式化的东西),然后通过检查代码实际在做什么。
这个开发人员对C ++中对象复制的理解存在严重问题。 这个例子本身就是一个WTF(如果该函数的开发人员真的使用了他/她自己的函数):
// Example call
strColHeader = insert_escape(strColHeader, ',', '\\'); //Get rid of the commas and make it an escape character
CString insert_escape ( CString originalString, char charFind, char charInsert )
strColHeader
的副本作为originalString
传递(注意没有&
) strColHeader
。 编译器可能会将其优化为单个副本,但仍然像这样传递对象副本对C ++不起作用。 人们应该知道参考文献。 一个经验丰富的开发人员会将此功能设计为:
void insert_escape(CString &originalString, char charFind, char charInsert)
要么:
CString insert_escape(const CString &originalString, char charFind, char charInsert)
(可能会将参数命名有点不同)
正如许多人所指出的那样,开发人员可以做的理智是检查API文档以查看CString
已经有一个Replace
方法......
如果你想要评估这个开发人员的C ++技能水平,我会说这证明了中级的低端。
代码完成了工作,并且不包含任何明显的“咆哮者”,但正如其他人所写,有更好的方法来做到这一点。
我不会提供替代代码,因为它只会添加到已提供的代码中。
但是,我的直觉是代码有问题。
为了证明这一点,我将列举原始函数中的一些要点,表明它的开发人员不是一位经验丰富的C ++开发人员,如果你需要一个干净的实现,你应该调查一下:
该顾问是否由代码行支付? 有几个人指出CString
类已经提供了这个功能,所以即使你不是程序员,你知道:
CString
函数可能有效并且可能有效; 这可能是也可能不是。 CString
函数已记录,因此是可支持的。 CString
函数,要么认为他/她可以通过编写新函数做得更好。
也许是最重要的,最红的标志:你的直觉促使你从StackOverflow社区获得意见。
相信你的直觉。
看起来没问题,如果有点,我不知道,黑客。 最好使用该库,但我不会去重写这个例程。
这是在Visual Studio C ++ 6.0中。
肠道反应: 发痒 。 认真! VC ++ 6附带的C ++编译器已知存在问题,并且通常表现非常糟糕且已有10年历史。
@Downvoters:考虑一下! 我非常认真地说这个。 VC6只是相对无效的, 不应该再使用了 ! 特别是自微软停止支持该软件以来。 有些情况下这是无法避免的,但很少见。 在大多数情况下,代码库的升级可以节省资金。 VC ++ 6只是不允许利用C ++的潜力,这使得客观上较差的工具。
看起来人们已经为你解决了这段代码的一些功能方面,但是我建议你不要像你在这里使用的那样改变命名。
除了UI控件之外,通常不赞成使用匈牙利表示法。 这对数字更重要......例如:
我宣布:
float fMyNumber = 0.00;
然后我在整个应用程序中使用它。 但后来,我将其改为双,因为我意识到我需要更高的精度。 我现在有:
double fMyNumber = 0.00;
确实,大多数优秀的重构工具都可以为您解决这个问题,但最好不要附加这些前缀。 它们在某些语言中比其他语言更常见,但从一般的风格角度来看,你应该尽量避免使用它们。 除非你使用记事本,否则你可能有类似于Intellisense的东西,所以你真的不需要查看变量名来确定它是什么类型。
总是有更好的实施。 如果您使用该功能作为顾问不是很好的示例,您可能还需要考虑,虽然他们不知道已经存在的功能,但他们可能有项目构建的经验和理解。
软件开发不仅仅是完美的功能,还包括整个架构的结构。
当我看到一个do ... while循环时,我总是担心; IMO他们总是很难理解。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.