【问题标题】:C++/CLI: Console::WriteLine() or cout?C++/CLI:Console::WriteLine() 还是 cout?
【发布时间】:2014-09-26 13:18:57
【问题描述】:

我要回学校去上 C++ 课。 我熟悉这种语言,但有一些我从未听说过的东西......

一般来说,我的老师说普通的 C++ 是“不安全的”。它会生成“不安全代码”(无论这意味着什么)。这就是为什么我们必须使用 C++/CLI 来编写“安全”代码的原因。

现在... CLI 不只是 Microsoft .NET 扩展吗?

他还告诉我们使用Console::WriteLine() 而不是cout。因为Console::WriteLine() 是“安全的”而cout 是“不安全的”。

这一切对我来说似乎很奇怪......有人可以澄清一下吗?

谢谢!

【问题讨论】:

  • .Net 有“安全”和“不安全”的概念,但总的来说,听起来你的老师是个白痴。 C++/CLI 是一个 Microsoft 扩展,允许 C++ 代码使用和使用 .Net 库。为纯 C++ 代码创建包装器非常好。但这不应该在 C++ 课程中教授。
  • 您的老师告诉您的是使用 Microsoft API 而不是标准 API。如果课程的全部内容是关于教你 C++/CLI(特别是),那很好,但如果他要教你 C++,那是相当糟糕的做法。
  • 我认为他们指的是 managed code 与非托管代码。
  • 另外,如果您正在编写 C++,请使用 C++ 库和类,如果您正在编写 C++/CLI,请使用 .Net 库和类。如果您正在努力弥合两者,则必须来回转换。
  • 嗯...我以为我们会从头到尾检查所有内容...例如类型、变量、if/else 等。但他只是直接跳入 Visual Studio Windows 窗体插件并明确告诉我们不要触摸任何生成的代码,因为他不知道如何使用它。是的,看来他是个白痴

标签: c++-cli


【解决方案1】:

说的很直白。

安全

您的老师所说的“安全代码”可能是指托管代码。那是您不必“关心”指针和内存的代码,您有一个垃圾收集器可以为您处理这些。您正在处理参考文献。像这样构建的语言示例是 java 和 c#。代码被编译为“虚构”操作码(中间语言,C# 的 IL),并实时编译和运行(JIT,即时编译)。 IL 生成的代码必须转换为真正的基于原生平台的操作码,在 java 中这是 jvm 所做的事情之一。您可以轻松地从这些语言中反汇编代码。它们可以在多个平台上运行而无需重新编译。

不安全

老师所说的“不安全代码”是指普通的原生 c++非托管代码,所有内存和资源管理都由您处理。这为人为错误、内存泄漏、资源泄漏和其他内存错误留出了空间,您通常不会在托管语言中处理这些错误。它还编译为纯字节码(本机汇编操作码),这意味着您必须为您打算定位的每个平台编译代码。您会遇到必须为每个平台编写大量代码,具体取决于您要编写的代码。很高兴看到简单的东西,例如依赖于平台的线程,现在是 c++ 标准的一部分。

然后你就有了 c++/CLI,它基本上是一个混合体。您可以在 c++ 中使用 .net 框架中的托管代码,它可以用作桥梁,用于制作包装器。

Console::WriteLine() 是托管的 .net 代码,安全。

cout 是来自<iostream> 的标准iso c++,不安全

You find a related post here, with a broader answer herehere :)

编辑

正如 Deduplicator 在此 is also of interest for you 下方指出的那样

希望对你有帮助。

干杯

【讨论】:

  • 同样有趣的,C# 中的不安全代码:msdn.microsoft.com/en-us/library/chfa2zb8.aspx
  • @Deduplicator +1+1 ;) 很好,我没有时间在这里写学术答案,忘了提那个关键字。
  • 谢谢,这说明了一切!
  • 如果“所有内存和资源管理都由你处理”,那么你写的 C++ 是错误的。它应该由智能指针和集合类来处理。
  • @BenVoigt 正如直截了当地所说的那样,我没有时间在帖子中写下所有内容,而且这并不完全是学术性的。我会看看我以后有没有时间修改它。为您的回答 +1。
【解决方案2】:

在 .NET 的世界中,“安全”是“可验证”类型安全的同义词。在 Visual C++ 中,它由/clr:safe 启用。

/clr:safe 将阻止您使用std::cout 或在本机代码中实现的任何其他函数或类型,因为本机函数不存在 .NET 验证程序所需的元数据。 Stigandr 提到的 MSIL 可用于即时编译,但即使提前执行本机代码编译,MSIL 也会与已编译的本机代码一起提供,并用作验证者检查的类型安全性证明.

标准(本机/非托管)C++ 会在编译期间检查类型安全。但这可以通过强制类型转换禁用,并且没有运行时类型检查,C++ 没有作为语言的一部分提供,指针算术(例如数组索引越界)也可能违反类型安全,就像使用指向释放对象的指针一样。 C++ 不仅仅是一种语言,它还是一种标准库,您可以在其中找到执行必要运行时检查的智能指针和智能集合,因此它可以像任何托管框架一样具有类型安全性。

【讨论】:

  • @Alf:不幸的是,证据表明老师正在(错误地)按照 Stigandr 所说的方式使用它,作为“管理”的同义词。
  • IIRC,在 C++/CLI 中 std::cout 是托管(但仍然不安全)代码。
猜你喜欢
  • 2013-05-09
  • 2011-03-20
  • 1970-01-01
  • 2021-07-26
  • 2021-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-28
相关资源
最近更新 更多