【问题标题】:What Gotchas When Learning C++, If I came from PHP/Java?如果我来自 PHP/Java,学习 C++ 时会遇到什么问题?
【发布时间】:2010-03-30 01:58:16
【问题描述】:

我需要学习 C++ 才能学习构建诺基亚 WRT 和/或 maemo 应用程序。 我需要知道我需要/必须学习或更多关注的 C++ 的哪些问题和哪些方面。 我想到的一件事是 C++ 没有垃圾收集器。因此,我需要关注变量类型。但是,还有其他什么是真正重要的,我不能忽视它吗?

【问题讨论】:

  • 您可以从 C++ 陷阱列表开始:stackoverflow.com/questions/30373/…
  • 我认为 C++ 比 PHP 复杂得多(因为没有更好的词),而且你不只是学习 PHP/Java 和 C++ 之间的区别......你学习 C++。
  • 是的,我知道我必须学习 C++。也许我的措辞是错误的。我只需要知道我需要更多地关注语言的哪一部分,这样我就可以将学习时间集中在那个特定方面。
  • 如果我是开拉达/保时捷来的,在学习驾驶 F1 时要知道什么?
  • @Wizard:更像是“我真的很喜欢冲浪和骑自行车。我被邀请参加冬季两项。在我开始之前有什么建议吗?”。除了“带上暖和的衣服”之外,选择少数问题有点困难:-)

标签: java php c++ qt-maemo


【解决方案1】:

主要问题是尝试设想 C++ 与 PHP 或 Java 的不同之处。

对不起,它只是不能那样工作。除了算术语法之外,C++ 在几乎所有重要方面都与这些语言不同。有时差异是微妙的。你需要重新学习它,不要认为在 PHP 或 Java 中适合做的事情在 C++ 中对你很有效。

也就是说,常见的困难包括:

  • 资源管理:RAII;实现复制构造函数、析构函数和operator=;避免必须实现 copy ctors、dtors、operator=。
  • 了解什么是引用、指针、值和自动变量。
  • 避免未定义的行为(myarray[i] = i++; 是最喜欢的)。 PHP 和 Java 都是比 C++ 更“严格”定义的语言:首先,程序的行为更可能被定义,因此更可靠。因此,单独的实现比 C++ 实现更相似。用 C++ 编写一个程序非常容易,它不仅会做错事,而且在不同的运行过程中会做完全不同的事情,包括崩溃、损坏数据等。
  • 学习安全有效地使用模板、多重继承、运算符重载和其他您不熟悉的功能。
  • 抛出和捕获异常的正确习惯用法(按值抛出、按引用捕获、不要从析构函数中抛出)。
  • 编写可移植代码(了解标准保证的内容与未保证的内容之间的区别,但您的实现恰好可以做到。实现定义的行为,例如基本类型的大小)。
  • 与 Java 或 PHP 相比,C++ 的标准库是有限的。您还将使用非标准库。例如,Maemo 使用 GTK+ 和/或 Qt。通常,“我如何在 C++ 中做 X”的答案是,“你不能只使用标准 C++ 来做,你需要特定于平台的 API 或为你的系统编译的可移植库”。 X 可以是图形、套接字、正则表达式、多线程、XML 处理、加密。尤其是在移动平台上,您需要密切关注操作系统版本,因为您会不时地发生变化。

【讨论】:

    【解决方案2】:

    立即学习使用 STL 容器。虽然迭代器语法对来自其他语言的人不友好,但它为您提供了您通常在 Java 集合或 PHP 中作为内置使用的内置数据结构(映射/哈希、列表、堆栈、向量),而无需编写时髦的指针代码动态分配经常让初学者陷入重新发明轮子和搞乱内存错误。

    此外,如果您编写特定于平台的代码(例如 Qt 或 Microsoft MFC 应用程序),您经常会看到使用特定于框架的容器的示例,其中 STL 将是更明智的选择。 STL(和 Boost)可以填补空白。使用 GUI 框架并不意味着您必须使用框架提供的所有内容。远离非标准容器,除非您毫无疑问地知道自己永远不会移植程序或重用部分代码。

    【讨论】:

      【解决方案3】:

      我会说它不是变量类型,而是确保你清理你的内存。 Java 会清理你的内存,但 C++ 不会帮你清理。否则,在出现异常时管理资源很重要。

      从好的方面来说,您将获得他们所谓的“确定性最终确定”。巨大的好处。查找,作为首字母缩略词,“RAII”。我认为它可以说是 C++ 中最重要的习语之一。

      它代表“Resource Acquisition Is Initialization”,但真正的意思是“当这个析构函数触发时,我会在你之后清理,即使存在异常。”实际上,这意味着,您创建或打开的任何需要关闭或删除的对象,都可以使用智能指针来保存。智能指针将在您之后清理。一旦您了解并开始使用它,这将非常非常强大。它使您的错误检查、异常处理和资源清理代码非常简单。

      【讨论】:

      • “我认为它可以说是 C++ 中最重要的成语之一”——而我持有另一种观点,它无疑是 C++ 中最重要的成语 ;-)
      【解决方案4】:

      我看到一些 Java 程序员在过渡到 C++ 时遇到的一个问题是“try-catch”内存泄漏。例如:

      try {
        myType pVar = new myType();
        DoSomething(pVar);
        delete pVar;
      }
      catch (exception) {
        cout << "Doh!  Something failed!" << endl;
      }
      

      在上述情况下,如果“DoSomething() 方法抛出异常,pVar 将永远不会被删除,因此会出现内存泄漏。

      (对此的解决方案包括:在 try/catch 块之前声明所有变量,使用 auto_ptr,或者只是避免从 try-catch 开始!)

      【讨论】:

        【解决方案5】:

        (在我看来)最重要的是一切都是值类型,所以如果你将数组传递给这样的函数:

        void do_stuff(std::vector<int> my_array)
        {
          ...
        }
        

        那么传入的my_array 是指定参数的副本。像这样复制整个数组很昂贵,所以一般来说,您希望通过 const-reference 传递:

        void do_stuff(const std::vector<int>& my_array) 
        {
          ...
        }
        

        (注意:如果要修改原来的my_array,请省略const)。

        【讨论】:

          【解决方案6】:

          我很好奇为什么“PHP/Java”在这里被视为一个单一的东西。不是。

          • Java->C++ 转换相当大,但它是可行的,你只需要学习很多额外的语法,一些额外的概念,如析构函数、复制构造函数、对象切片和运算符重载,并接受C++ 库。
          • 另一方面,PHP->C++ 转换又大了一个数量级,因为它涉及 (a) 一种定义非常差的源语言,(b) 一种基于模板而不是基于类的语言, (c) 在特殊环境中执行的语言。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-02-04
            相关资源
            最近更新 更多