当我从C& C转型时,我有什么期望会有所不同? C#到C ++?

时间:2008-12-24 12:26:27

标签: c# c++ c

这是一个简单的问题。

我使用C& C完成了很多工作。 C#(2.0),但在C ++中从来没有。学习C ++时,我可以期待什么不同?我是否应该注意任何重大问题或障碍?有没有人为有经验的程序员学习C ++的课程书/网站建议?

14 个答案:

答案 0 :(得分:14)

我能想到的主要区别是C ++远不是C和C#的多范式语言。在C#中,OOP仍然是 范例。它之前是OOP语言,如果你没有做OOP,C#社区会告诉你你做错了。 (尽管C#在过去的几年里也为一些函数式编程提供了很好的支持。)

在C ++中,OOP是支持的,你可以在你喜欢的时候使用它,但所有的大惊小怪都是围绕通用编程。 C ++模板允许广泛的聪明,可重用和通用的库,并实现许多与旧式OOP相同的目标,但没有大的继承层次结构,并且几乎没有类之间的耦合。标准库包含许多此

的示例

在C ++中,很多C构造虽然仍然合法,但基本上是避开的:

  • 原始指针(通常替换为智能指针,例如boost::shared_ptrstd::auto_ptr,或带参考
  • 用户代码中的内存分配(通常应包含在智能指针中或定制的RAII对象中)
  • 函数指针(通常用仿函数替换,以获得更好的类型安全性和性能)
  • goto(经常在C中使用以跳转到清理代码。再次,RAII没有必要)
  • 预处理器(几乎从不需要。更喜欢模板)

当然,这些要点中的每一个都有例外,但作为一般的经验法则,与C代码不同,C ++代码几乎可以消除对这些内容的所有使用。

而且在C#中,课程确实是很重要的工作。在C#中,一个类只不过是一个脚手架,一个容器可以粘贴你所有的方法。当然,它有一个构造函数,它可以实现Dispose();但C ++更进一步,你有:

  • 构造函数(就像在C#中一样,从头开始初始化类)
  • 复制构造函数(将类初始化为另一个对象的副本)
  • 赋值运算符(因为类是C#会考虑的值类型。所以赋值不只是更改引用,而是以用户定义的方式复制对象的所有内容)
  • 析构函数

析构函数可能是 在C ++中最重要的概念。对RAII来说至关重要,这就是内存或其他资源的管理方式,因为当对象超出范围时会自动调用它。这允许您的类在C或C#中实现许多无法实现的保证。 例如,boost :: thread提供了一个范围锁,当它超出范围时,保证释放,无论函数是否正常返回,抛出异常,还是其他任何东西。因此,在使用此库时,用户不必担心释放锁或其他资源。只要你完成它们就会自动发生。

从某种意义上说,这为您提供了更多的钩子来定制您的类的行为。与C#不同,您可以精确控制执行简单赋值时发生的情况。您可以控制当类超出范围,从头开始初始化或作为另一个对象的副本时发生的情况。这使得编写良好的类几乎不可能错误地使用。 (几乎)

除此之外,模板和模板元编程是您可能会遇到的概念。它们是非常强大的工具,因此请确保您与他们保持友好关系。 :)

答案 1 :(得分:8)

以下是我的观点:

  • 指针在C ++中扮演重要角色。 在C#中你只有参考 类型。你可能会头疼 指针错误。
  • 您还必须管理 手动分配内存。和 您的计划有机会 如果这样,将会遇到内存泄漏 没有做好。在C#中,每一个 对象是垃圾收集的, 自动。
  • 声明和定义 课程通常是分开的 标头文件(.h)源文件 (.cpp或.cc)。这将导致一个 起初有点困惑。
  • 你不会有这么多的基类 C ++中的库支持与C#一样。对于 例如,你不会有 {C>内置的HttpRequest类。
  • 因此,你必须使用一个 很多外部图书馆和知道 如何处理.dll或.lib。
  • C ++与C#中没有Interface。您 将使用抽象类(和 而是多重继承)。
  • C ++中的字符串是一个char数组或 指向char的指针。
  • 有一些算法和数据 结构可供使用 标准模板库(STL。)但是 你需要时间学习 可以开始有效地使用它:)

您还可以学习C ++ / CLI,将.NET代码和本机C ++混合在一起,以实现两全其美。

答案 2 :(得分:4)

我强烈建议:“有效的C ++和更高效的C ++”。如果您正在使用它,“Effective STL”可能会有所帮助:)

这些书是专为需要有效处理C ++的智能程序员编写的。我证明,当我开始使用C ++时,Effective C ++是帮助我的人!

C ++初学者的另一本好书(但我不认为是计算机初学者)是“Accelerated C ++”。它主要关注良好的编码,stl和生成高级代码,而不是关注细节。 (这些在本书的最后更多地展开了)。

祝你好运:)

答案 3 :(得分:3)

我已经使用C ++超过10年了,所以我的答案是,学习严格的内存管理,C ++模板,STL,然后是Boost。这应该花费你几个月,然后细节将带你说5年:))

至于我喜欢Herb Sutter的Exceptional C ++和更优秀的C ++的书籍

答案 4 :(得分:2)

嗯......笨蛋。如果你对.NET和指针没问题,那就不应该有太多的新内容了。

我认为处理C ++头文件将是一种体验。还有C ++ STL让你熟悉。

您可能还需要与人们讨论多重继承等事情。

答案 5 :(得分:2)

我从Asm转到C,C ++,......以及最近的C#。它可以解除能够实例化对象并从方法或属性返回它们。通常,实现和用户代码都不必担心释放内存。此外,在大多数情况下,没有理由返回状态代码,例如HRESULT,因为如果出现问题,则抛出异常并让用户代码在需要时处理它。

最近切换回我上一个项目的原生C ++代码,我真的很想念垃圾收集和异常抛出。

但是,我确实喜欢C ++的模板功能。有一天C#应该扩展这项技术。

答案 6 :(得分:1)

我看到有几个人指出内存管理是一个大问题,因为你必须手工完成。好吧,不要相信他们,这是错误的。除非您处于异国情调/老式环境中,否则C ++会提供一些工具来帮助我们隐式地和确定地管理内存(以及任何其他资源)。请参阅boost / std :: tr1 shared_ptr<>和RAII。

与GC收集记忆的最大区别是:你必须自己照顾周期。

关于多重继承,一旦你掌握了LSP所暗示的内容,它也不是什么大问题。

我必须同意pheze的消息:如果你想教你如何(/应该?)使用C ++,那么 Accelerated C ++ 是必读的。< / p>

答案 7 :(得分:1)

Jalf完全正确 - 来自C / C#背景,你几乎已经知道了你需要的所有基本C ++,而且你也知道OOP,所以你做得很好。

有两件事会浮现在脑海中,对你来说是新的:

  • RAII:这可让您拥有自动内存管理功能,您不再需要记住释放所有内容。好吧!它还可以帮助处理所有其他资源,您不再需要记住关闭该套接字,文件,数据库连接 - RAII会为您完成。 C和C#都没有这个。

  • STL / Boost:这是'C ++类库',充满了有用的实用程序和位。所有标准容器都在STL中(如“字典”和“数组”和“列表”)以及可以应用于它们的算法(例如,如果您有一个数据项列表,则可以提供一个小函数对象(称为一个仿函数),然后将两者都传递给通用算法。这非常强大,你可以用它做很多工作。)

答案 8 :(得分:1)

主要的不同是C ++是基于价值的,而C#是基于参考的。

在C#中,当你将一个对象传递给一个方法时,你实际上只是传递一个引用,所以调用方法和被调用的方法都在查看同一个对象。

在C ++中,将对象传递给方法时,会生成该对象的副本,并将整个副本传递给该方法。被调用方法对副本所做的更改不会影响调用方法中的原始方法。可以使用引用语法在C ++中模拟引用行为:

void somemethod(someclass& obj);

答案 9 :(得分:0)

最大的“障碍”可能是你将负责释放你分配的内存

答案 10 :(得分:0)

已经发布了,你可能会对你的内存管理负责,但其他只是学习C ++库以及如何组织它们,我认为它根本不应该是一个艰难的转换。

答案 11 :(得分:0)

关于语言实现的差异 - 我认为你需要小心内存管理,标题中的声明等等 - 我认为最难处理的是额外的特殊重载语法中的字符。经过多年编写C#代码之后,我偶然发现的所有内容都是额外的*&<>。我的第一反应是C ++代码看起来很像正则表达式。

我敢肯定,一旦你使用它一段时间就会消失,但我不再做足够的C ++了,我知道在每种情况下确切使用哪个符号 - 我是否已经过了指针或对该对象的引用?

另一个重要问题是,无论如何,当读取其他人的代码时,操作员会超载。我知道你可以用C#来做,但我很少看到它在那里完成。可能事情已经发生了变化,但我曾经在C ++中看到很多运算符重载,其中+/-会产生一些奇怪的效果。除了一些相当明显的胜利(比如字符串连接)之外,我认为这实际上是一个我可以做到的可疑功能 - 在C ++和C#中。

答案 12 :(得分:0)

  1. 内存管理
  2. 更复杂的语法
  3. 内存管理
  4. 整个OOP生命周期中的工具支持少于C#。
  5. 内存管理
  6. 我是否提到了内存管理?

    我一直认为利用市场作为一部分人口感知需求的指标很有意思。考虑到(为了对比)VB市场,组件库似乎是主要的重点。然而,从最初的日子开始,C ++(和C)市场中的主要产品似乎就是内存管理,泄漏检测和代码质量工具(例如类似lint的检查员)。

答案 13 :(得分:-3)

类之间的循环引用[在C ++中]。如果你问我,C ++中的OOP真的很有用。

编辑:好的,我想有更多的细节。说你有: Foo和班级Blah。类Blah引用类Foo,类Foo引用类Blah。假设你走的是天真的路线,你可以像这样实现它:

#include <blah.h>
class Foo {
    Blah blah;
    ...
}

和Blah:

#include <foo.h>
class Blah {
     Foo foo;
     ...
}

那可能行不通。相反,您需要使用前向引用,即Foo变为:

class Blah;

class Foo {
    Blah blah;
    ...
}

如果你用谷歌搜索“C ++中的循环引用”,你会明白为什么我在这个问题中提到它。现在停止投票让我失望...