经验丰富的 C++ 程序员在 C# 开发中最常见或最严重的错误
Posted
技术标签:
【中文标题】经验丰富的 C++ 程序员在 C# 开发中最常见或最严重的错误【英文标题】:Most common or vicious mistakes in C# development for experienced C++ programmers 【发布时间】:2010-03-11 12:25:15 【问题描述】:当有经验的 C++ 程序员使用 C# 开发时,最常见或最严重的错误是什么?
【问题讨论】:
社区维基,也许吧? (PS - “主观和争论”的结束投票,我不同意。我认为这个问题不太可能导致争论!;) 【参考方案1】: 两者中struct
和class
的区别
using
别名和typedef
之间的区别
什么时候收集我的物品?我该如何销毁它们现在?
int
有多大? (其实是用C#定义的)
我的链接器在哪里? (实际上,对于某些场景,Mono 确实有一个完整的 AOT 链接器)
【讨论】:
int 有多大。定义明确的语言和环境的乐趣:) 我觉得有义务指出 C++ 对其实现进行了定义,以便编译器可以使用性能最高的本机类型,而不是受到规范的限制。如果您需要,有可用的尺寸类型。 @Mark 在 C99 中有stdint.h
。这在标准 C++ 中还不是。 (它在 tr1 中,但未在 MSVC 2008 中实现)请参阅 stdint.h 上的 wiki 条目
@KitsuneYMG :是的,它在 C 标准中,而不是 C++ 标准中,这就是为什么它在 VS2008 中不受支持,即使在他们的 TR1 中也是如此。但是它是在 boost 中并且它只是标题,所以它不会让你的 exe 变得更大;)【参考方案2】:
我见过许多 C++ 程序员在 C# 中以 COM 风格编写代码,试图处理语言的不足之处。 C# 为您的枚举提供了大量类型安全的支持,并且通常有更好的 API,然后 P/Invoking 回到 C++。
我看到的另一件事引起大多数人的注意是 C# 泛型不是模板。
【讨论】:
【参考方案3】:致电GC.Collect
。
【讨论】:
+1。我见过程序员担心他的对象会留在内存中的代码,他不断地调用它。【参考方案4】:-
一直使用结构来支持类。
一直使用 in、out 和 ref 参数(这是第 1 点的结果)。
使用 int 值作为错误条件而不是使用异常
使用 virtual 关键字而不是 override 关键字。
认为 char 是 8 位有符号值。
【讨论】:
前三个听起来更像是 C 程序员会犯的错误......或者可能是非常糟糕的 C++ 程序员。 C++ 程序员,就像 C 程序员一样习惯于认为大多数时候使用值类型就可以了。 #3 在 C++ 和 C# 中同样错误;它看起来更像是 C 程序员使用这些语言中的任何一种都会做的事情。 Re #3:“返回代码被认为是有害的”?很抱歉,但如果您需要收集中间结果并需要继续进行,例外是不允许的。枚举返回码有它们的位置。使用 try catch 来控制“常规”流程并不是最好的主意。【参考方案5】:认为“垃圾收集”=“我根本不必担心对象的生命周期”。例如,打开FileStream
却忘记关闭它。
或者:
-
分配大量对象
将它们放入一个大的全局字典中(通常在“我知道,我会做一个缓存”之后)
想知道为什么应用程序的内存使用量总是上升而从不下降(“但它应该进行垃圾收集!”)
【讨论】:
FileStream
不会像 fstream
那样在其析构函数中关闭吗?
@henle:你不知道什么时候会调用析构函数,所以最好手动调用dispose,或者使用语义。
好吧,在 C++ 中,你确信一旦变量超出范围,析构函数就会被调用,所以通常不需要显式地处理资源(这是 RAII 的重点) .
当 CLR 需要回收内存时,会调用 FileStream
终结器。如果有足够的可用内存,那么在程序退出之前FileStream
可能不会最终确定。
.NET 终结器与 C++ 析构函数不同。如果清理代码不重要,那么您可以将其留给垃圾收集时间(最终确定)。如果您确实需要确定性清理——比如关闭文件句柄——请致电IDisposable.Dispose
。【参考方案6】:
混淆“按引用传递”和“引用类型”:
void GetAnArray(int input, ref string[] output);
(与 C++ 比较:void getAnArray(int input, std::vector<std::string>& output);
)
【讨论】:
【参考方案7】: RAII 与 IDispose 值类型与引用类型(结构与类、装箱和拆箱等)【讨论】:
【参考方案8】:每次都编写完整的命名空间。
当您键入 std::this
或 boost::that
时,这在 C++ 中很好。当你到处重复 System.Windows.Forms.Whatever
时,在 C# 中就不那么好了。
【讨论】:
【参考方案9】:顺便说一句,C# 编译器中有许多启发式方法可以帮助有经验的 C++ 程序员和新手 C# 程序员。例如,如果你说
int x[];
编译器会帮助指出 [] 是 C# 中类型的一部分,因此您可能的意思是
int[] x;
C# 还允许在类声明的末尾放置不必要的分号,这样有这种习惯的 C++ 程序员就不会被它所困扰。
【讨论】:
【参考方案10】:忘记为每个类成员指定访问修饰符。
【讨论】:
@Judah Himango:我的意思是,在 C++ 中,您为不同的访问区域使用标签。我经常发生在方法之前忘记写public
,因为之前的方法也是公开的。我看到这种情况一直发生在学习 C# 的 C++ 程序员身上。【参考方案11】:
尝试在string
s 上实现const
的正确性。
【讨论】:
【参考方案12】:我相信很多非 C++ 人也是如此,因为注册事件使对象保持活动状态而导致内存泄漏。
IDisposable 一开始就被磨碎了(如果我说实话,现在仍然如此),但从本机代码到托管代码时显然会有所不同,所以我不希望 C++ 开发人员真正犯规,他们就是不喜欢。
【讨论】:
【参考方案13】:使用匈牙利表示法和其他 C++ 命名约定
private int m_iMyIntField;
class CWidget ...
【讨论】:
误用的匈牙利表示法并不是 C++ 特有的,它更像是 WIN32 和 MFC 库的产物。 你的意思是像 IMyInterface 或 MyException?以上是关于经验丰富的 C++ 程序员在 C# 开发中最常见或最严重的错误的主要内容,如果未能解决你的问题,请参考以下文章
TIOBE 5月编程语言榜单出炉,C#最受开发者欢迎,C++将冲击Top 3
三年的python开发经验,总结出这30个常见错误,避免重蹈覆辙!!!