草庐IT

c++ - C:良好习惯:过渡到C++

coder 2023-05-31 原文

我在Varsity学习C的时间不到2个月,明年我们将继续使用C++。

我应该在C编程中养成什么习惯,以帮助将来向C++过渡,还是最好完全分开考虑它们?

当您学习C和C++时,用C编码的方式是否发生了任何变化?

最佳答案

已经有很多好的答案。我的将更“以心态为导向”​​。
数据与行动!

  • 在C语言中,所有事情都像“将这种效果应用于此数据”一样进行思考。
  • 在C++中,这更像是“数据应该表现”。

  • 尽管“数据应该表现”可以在C语言中完成(而且确实可以完成!),但在C++中,轻松实现此功能所需的一切都已经可以访问:封装,构造函数,重载覆盖,模板等。
    我发现在使用C++进行编码时,这种“数据应该表现”的想法是一个很好的指导原则。
    C++语法糖不是可选的
    您会发现很多可以用C语言完成的C++功能,有些人以此为借口不学习它们。这种心态是危险的(在某些帖子中看到的是“将C++作为一种新语言,而不是扩展”)。
    避免以C++方式编写C++的副作用是,尽管C++开发人员应该理解C++代码,但他/她不应该了解您的小个人框架,该框架模仿仅具有C功能的C++糖。实际上,他/她对您的框架不会感兴趣。说实话,他/她只会为您感到可惜/鄙视,因为您浪费了宝贵的时间来创作。最终,如果他/她必须使用您的框架而不是C++糖,那么他/她将恨您。
    诸如“我可以用C方式做到这一点”之类的指导原则只会让您错过旅行车。如果您已经有了这种以C为中心的思维方式,最好不要完全开始学习C++。
    您选择的语言永远不会是最好的。你应该成为最好的。如果您编写C++代码,请以C++方式编写。
    C兼容C++代码是语义错误
    对结构进行Typedef定义以使其可以由C编译器编译是一个不好的 Jest 。使用指针而不是引用是对自己 future 的一击。 extern "C"只会使您的代码更弱而不是更强。并且使用void *进行通用只会增加其他C++编码人员的数量,他们愿意为以惊人的痛苦的方式卸下头部而高兴。
    除非真的需要,否则不要费心编写C兼容代码。
    您将以一种费时的编码风格来减轻自己的负担,而这是您永远不会使用的功能。
    编译器是一个强大的 friend /敌人
    低级工作会对某些开发人员产生奇怪的影响。他们相信自己对已编译代码的控制。对于他们来说,将控制权委派给更高层次的构造是困难的。
    一个很好的例子是放弃构造函数/析构函数模式,因为“有时构造函数会花费太多时间……最好以我的方式来做……”。
    C++编译器完全有能力优化似乎未优化的代码。实际上,编译器产生的代码可能与您认为产生的代码完全不同。
    不要尝试比编译器更好/更聪明,因为:
  • 您可能已经失去了战斗,因为即使是旧的编译器通常也会产生比您今天梦dream以求的更好的代码。
  • 即使您今天赢得了这场战斗,明天它也会自动变成失败,因为将来编译器会变得越来越好,因此,您今天的“优化代码”将成为 future 几年的程序瓶颈和重构主题。 (更不用说为您留下可耻的记忆了)。

  • 因此,请信任您的编译器。
    不要对代码的生产进行微管理。自己做,让编译器自己做。
    请注意,这一点不应用于证明产生慢速/无效代码的合理性。如果过早的优化是万恶之源,那么您仍然必须使用对语言的了解和编译器来生成良好而高效的代码(请参阅下一点)。
    了解每个C++构造的优点/后退/成本
    例如,对于某些人来说,虚拟方法为函数调用方法增加了一种间接性,这会导致性能急剧下降。事实是,性能问题通常在其他地方。
    无知不是借口。
    了解为每个C++构造生成的代码(即内联,引用,构造函数,析构函数,异常,函数重载,函数重写,模板,虚函数等)。知道哪些将被优化,哪些将不会被优化。
    这样,不仅您不需要为不需要的东西付钱(这是C++的指导原则),而且您还将从零成本带来的 yield 中受益,但带给您很多好处。
    要谦虚
    有一些人在C++方面进行研究,他们出生的那一天在C++方面的表现比我们大多数人都更好。即使我们忽略Stroustrup,像MeyersAbrahamsAlexandrescuSutter等名称也经常随着新的想法而出现。尽管(或由于其外在的观点)STL是革命性的图书馆。像Boost这样的库,尽管与某些完整的框架(如Java或.NET API)相比“很小”,却是一个庞大的优秀代码库,供您学习。
    仅仅因为您发现了一些新功能“奇怪”或“异形”,请不要低估它。试图理解它将会使PERHAPS为您带来另一种工具供您使用,并且将始终提高您对语言的掌握程度,并且将使您的大脑正常工作,这在开发业务中是一件好事。
    我认识的大多数人都失败了,他们“转换为C++”只是认为此功能或此功能无用,因为他们不愿意去理解它。
    RAII !!!!
    如果您不知道它是什么,请学习它。
    如果没有RAII,您的C++代码只是错误的代码,避免了编译错误。
    RAII是C++最重要的一个概念。
    其他一切都相关。

    关于c++ - C:良好习惯:过渡到C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1420685/

    有关c++ - C:良好习惯:过渡到C++的更多相关文章

    1. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

      我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

    2. ruby - 使用 `+=` 和 `send` 方法 - 2

      如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

    3. ruby - 如何计算 Liquid 中的变量 +1 - 2

      我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

    4. arrays - Ruby 数组 += vs 推送 - 2

      我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“

    5. += 的 Ruby 方法 - 2

      有没有办法让Ruby能够做这样的事情?classPlane@moved=0@x=0defx+=(v)#thisiserror@x+=v@moved+=1enddefto_s"moved#{@moved}times,currentxis#{@x}"endendplane=Plane.newplane.x+=5plane.x+=10putsplane.to_s#moved2times,currentxis15 最佳答案 您不能在Ruby中覆盖复合赋值运算符。任务在内部处理。您应该覆盖+,而不是+=。plane.a+=b与plane.a=

    6. ruby - Sinatra + Heroku + Datamapper 使用 dm-sqlite-adapter 部署问题 - 2

      出于某种原因,heroku尝试要求dm-sqlite-adapter,即使它应该在这里使用Postgres。请注意,这发生在我打开任何URL时-而不是在gitpush本身期间。我构建了一个默认的Facebook应用程序。gem文件:source:gemcuttergem"foreman"gem"sinatra"gem"mogli"gem"json"gem"httparty"gem"thin"gem"data_mapper"gem"heroku"group:productiondogem"pg"gem"dm-postgres-adapter"endgroup:development,:t

    7. ruby - Ruby 中字符串运算符 + 和 << 的区别 - 2

      我是Ruby和这个网站的新手。下面两个函数是不同的,一个在函数外修改变量,一个不修改。defm1(x)x我想确保我理解正确-当调用m1时,对str的引用被复制并传递给将其视为x的函数。运算符当调用m2时,对str的引用被复制并传递给将其视为x的函数。运算符+创建一个新字符串,赋值x=x+"4"只是将x重定向到新字符串,而原始str变量保持不变。对吧?谢谢 最佳答案 String#+::str+other_str→new_strConcatenation—ReturnsanewStringcontainingother_strconc

    8. ruby - rails 3.2.2(或 3.2.1)+ Postgresql 9.1.3 + Ubuntu 11.10 连接错误 - 2

      我正在使用PostgreSQL9.1.3(x86_64-pc-linux-gnu上的PostgreSQL9.1.3,由gcc-4.6.real(Ubuntu/Linaro4.6.1-9ubuntu3)4.6.1,64位编译)和在ubuntu11.10上运行3.2.2或3.2.1。现在,我可以使用以下命令连接PostgreSQLsupostgres输入密码我可以看到postgres=#我将以下详细信息放在我的config/database.yml中并执行“railsdb”,它工作正常。开发:adapter:postgresqlencoding:utf8reconnect:falsedat

    9. ruby - 在 Ruby + Chef 中检查现有目录失败 - 2

      这是我在ChefRecipe中的一blockRuby:#ifdatadirdoesn'texist,moveoverthedefaultoneif!File.exist?("/vol/postgres/data")execute"mv/var/lib/postgresql/9.1/main/vol/postgres/data"end结果是:Executingmv/var/lib/postgresql/9.1/main/vol/postgres/datamv:inter-devicemovefailed:`/var/lib/postgresql/9.1/main'to`/vol/post

    10. ruby-on-rails - 使用 Pow 作为服务器在 RubyMine 中调试 - Ruby 2.1.1 + Rails 4 - 2

      我已经开始使用RubyMine6。我正在处理Rails4、Ruby2.1.1项目。我无法找到如何使用Pow作为服务器调试到RubyMine。你能给我指明正确的方向吗? 最佳答案 我能够使用远程调试从RubyMine进行调试。我正在使用RubyMine6、Rails3、Ruby2.1.1。首先创建一个.powenv文件并添加:exportRUBY_DEBUG_PORT=1234exportPOW_WORKERS=1将以下gem添加到您的Gemfile:gem'ruby-debug-ide'gem'debase'创建一个新的初始化器st

    随机推荐