从C#转向C++(同时在同一解决方案中使用两者)

13

这是一个非常普遍的问题。我是一个自学的C#程序员。如果我了解C++,那么我想要开发的项目会变得更加容易(从长远来看)。从C#转向C++有多容易?我应该注意哪些陷阱?如果我在使用VS2010,是否可以同时在同一项目中编写C#和C++代码(不在同一类中)?


14
在C++中,自己给自己挖坑并且受伤的可能性比较大,而且这种伤害比在C#中要严重得多。 - Uwe Keim
7
这太有趣了,我真的笑得很开心!谢谢! - formatc
2
@keynesiancross 很抱歉告诉你,你将面临一些非常艰难的日子,哈哈哈哈哈。 - Chani
4个回答

22
从C#转向C++并不容易。基本语法可能看起来相同(例如if,for...),但是存在深刻的差异,例如RAII模式和堆栈语义变量,它们的析构函数在超出范围时被调用等,在C#中不存在。
此外,C#使用非确定性垃圾回收器(对于内存资源可以接受,但对于其他类型的资源无用)。相反,使用现代C++,您可以使用模板和智能指针(如std :: / boost :: * shared_ptr *),它们允许您具有确定性的引用计数“垃圾回收”,这非常高效,并且适用于内存和非内存资源(如文件句柄,套接字,纹理等)。
此外,C#泛型与C++模板非常不同(C++模板非常强大,并允许一种称为“模板元编程”的高级编程水平)。
在VS2010中,您可以拥有同时托管C++和C#项目的解决方案。要在两个世界之间通信(C++的本地世界和.NET / C#的托管世界),您可以使用C++ / CLI作为一种桥接层。
在Windows 8中,应该引入一种新技术,称为WinRT(基于COM),它允许跨语言通信。在这种情况下,您可以使用C++和WRL(一个基于模板的库)或C++/CX语言扩展来构建C++组件,这些组件可以从C#和.NET中使用。
祝学习愉快。

1
感谢您的扎实回答。现在,诚然,我不知道您所说的前三件事是什么...(RAII / stack sematics??,非确定性垃圾收集器??和模板??) - keynesiancross
1
如果你提到了shared_ptr,那么你至少也应该提到它与GC相比的明显问题(循环引用、多线程、性能),否则这可能会给不知情的人带来有趣的惊喜。小提示:引用计数高效吗?实际上并不是。 - Voo
1
@keynesiancross:谢谢。关于RAII,您可能想考虑维基百科的文章。基本上,在C++中,您可能希望使用C++类来管理原始资源:类的构造函数获取资源,析构函数释放它(这适用于任何类型的资源,不仅仅是系统内存)。如果您在堆栈上定义此类的实例,则一旦实例超出范围,析构函数将被调用,因此资源将被释放。这是以确定性方式发生的。由于析构函数,您可以编写结构上无法泄漏的C++代码。 - user1149224
1
如果资源在不同的所有者之间共享,可以使用shared_ptr进行封装,它基本上使用引用计数来管理共享资源,并且一旦引用计数达到零(即没有人再引用该资源),则会释放它(即调用析构函数)。同样,这是一个确定性的过程(引用计数== 0 --> 资源被释放)。模板是表达通用代码的一种方式(例如:T的容器,其中T可以是字符串、整数、结构、自定义类等)。 - user1149224
1
@Mr_C64 如果您不理解为什么引用计数基本上是实现任何类型资源共享的最低效方式,我怀疑500个字符的空间足够解释所有原因。可以说,引用计数GC(基本上相当于shared_ptrs)由于其开销、不良可扩展性和循环问题,在现代GC算法中都没有使用。而且,使用GC来处理除内存以外的资源是一个坏主意——谁会争论这一点呢? - Voo
显示剩余2条评论

9
我是从c++转到c#的。在许多方面,这是一种解脱。C++比c#有更多的规则,特别是关于内存分配方面。语法也可能具有挑战性,很容易走向越界内存。然而,C++更适合系统级编程,但“大权利带来大责任”。
我建议首先获取Scott Meyer的Effective C ++的副本,并全面阅读。这是我知道的最好的资源,可确保基础正确,并且无疑提高了我作为“经验丰富”的c++开发人员所产生的代码的质量。然后获取一个单元测试框架,并查看c++ kata(在这种情况下是xcode项目,但仍应该有用)。并熟悉标准模板库,其中包含许多有用/高效的代码/类,用于容器、算法等。
最后,祝你好运。学习一门新语言总是具有挑战性的,可能会让人感到害怕,但通常回报是值得的。即使没有其他收获,你也会以全新的眼光看待自己的C#代码。

5

我是否可以在同一个项目中用C#和C++编程?

答案是否定的。你可以使用Managed C++ & C++,但如果你正在使用C#,则无法在同一项目中同时使用C#和C++代码。

从C#转到C++有多容易?

这有点主观,但我认为这将是一个非常困难的步骤。C++是一种不同的语言,所以学习起来就像学习一门新语言一样难 :) 再次强调,这是主观的,所以我不会详细解释。


5

因为您在使用.NET,我假设您正在使用Visual Studio?

使用/clr编译器选项将C#和C++合并到同一个程序中非常容易。您的C++代码可以包括普通的、符合标准的C++类,以及为从C#使用而设计的ref class.NET对象。这两者是独立的,但可以通过ref class到本机class的指针以及从本机classref classgcroot模板相互访问。

请注意,我说的是“在同一个程序”中,而不是“在同一个项目”中。您将不得不将其分成两个部分,一个是C#项目,另一个是C++/CLI项目,并且一个将是另一个加载的DLL。还有一个技巧可以在构建过程中将两者结合在一起,使您最终获得单个可执行文件,但通常不值得那么麻烦。


请注意,您可能会发现我编写的这个智能指针类很有用,它可以使从ref class.NET对象使用本机class对象变得更加容易。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接