近期玩VC心得

目前在日本項目組,用正體寫注釋(簡體經常出現無法顯示的情況),再由PL翻譯成日文.因此就懶得切換了(本文在溜號時間斷斷續續做成).看不懂的可以提問,但是俺不保證會回答.

干鳥快兩年的QA,對于質量保證沒學會多少,卻沾上了不少嘴高手低,橫挑鼻子豎挑眼滴毛病.這回換組真正碼的時候,才發現遇到好多雞零狗碎的問題.簡單記錄一下,怕忘.再說,中年妇女心得,我便心不得?

1) LINK2001失敗
可能原因:
α,類聲明時,頭文件裏的函數的參數類型定義與實現時的不符(某些時候不會報錯,但是會導致聲明該類的時候鏈接錯誤)
β,類不是MFC擴展類(AFX_EXT_CLASS)
γ,大小寫問題導致.其實與第一個是同一回事,比如在類裏聲明的是GetValue(),而在別處想以Getvalue調用,編譯不會出錯,但是在鏈接的時候會出錯.
δ,靜態變量未聲明
ε,目標/lib或/dll路徑只讀
ζ,Debug版試圖引用Release版lib,或者Release版試圖引用Debug版lib時
η,使用unicode卻沒有在unicode選項下編譯
θ,使用靜態庫卻沒有把庫加入工程

2) 調試時候的內存錯誤
α,聲明的指針沒有初始化,是最好找的問題
β,資源重復釋放(重復刪除句柄),也是很好找的問題
γ,數組下標越界
δ,引用空指針/野指針
ε,錯誤的函數調用,比如誤把itoa()的返回值當成字符串
ζ,錯誤的返回值.比如返回值類型string的函數,返回false也能夠編譯通過,但是別人在使用這個函數時會立刻報內存錯誤
η,類中有錯誤,只要引用了頭文件,即時沒有調用類裏的任何方法,也可能會導致內存錯誤.之前一次連入口都進不去,就是因為引用的類裏有錯誤ε
θ,alloc/free;new/delete的配對.俺們的客戶經常犯這種錯誤
ι,&和*的濫用,比較難找的一種問題

3) 注意大小寫.某些情況編譯不報錯,查找時相當的惡心
4) 注意生存周期.在不考慮速度和效率的情況下,用new的可以更好的控制你寫的東東的生存周期.當然要注意delete
5) 注意日文和某些字符,刪除的時候可能會刪一半,這樣就可能會出現無法通過編譯的字符
6) 有些東東能不往工程裏加就不要往工程裏加,能在頭文件和源文件裏寫出來就寫在那裏.不然改的時候不好改,別人想看得時候也找不到
7) 編碼規范說注釋很重要,但是明確的英文更重要.如果能夠在函數名和成員名裏都說清楚了,基本上不需要那么多的注釋,如果給自己看的話.要不不常用API函數名字怎么一個賽一個的長呢?
8) 協同工作的時候,要注意把工程文件一起checkout出去.雖然它可能直到交付都不會變
9) 引用的頭文件的位置很重要,有的時候編譯不過,試著改改stdafx.h裏頭文件的排列順序
10) 變量聲明的時候順手賦個初值. = 0; =””并不難寫,卻可以省不少麻煩
11) 記得要存檔,記得要存檔,記得要存檔!你用的不管是不是正版VC6,它愛自己死掉卻是不爭的實事.有的時候還會莫名其妙的丟文件.所以一定要適時存
12) VC6死掉的時候,要動用taskmanager殺進程.而且要在application裏殺,而不是process裏,不然再启动以后也木有办法編譯鳥
13) 調試滴時候,F10是單步,F11是進入,F5是跳到下一個斷點.前提是你編譯的是Debug版本.

已有3条评论

  1. 随便点了一下发现个2007年的文章,这个时间我还没看上大学。
    仔细想想本科学校也只教了 Turbo C ,跟没教也没什么区别。糊弄过了二级C之后也只有去北京找工作的时候做了点东西糊弄人。很荒唐的是这都8年过去了,最近一个月找我要这个项目源码的人都快一只手数不过来了了。
    连续玩了好多年PHP和JS,这些都是解释型语言。最近想了解下编译型语言,却无从下手了。兄弟你是这方面的,现在有啥C++相关的入门渠道给介绍下么?(不需要推荐其他语言,Go什么的我知道)

    1. 我也没系统学过C++,全是从项目里自己总结的野路子。
      你有PHP基础,语法差不多。要注意的是这么几个:
      一是变量。C语言的变量相对于PHP来说非常严格,在使用之前必须有明确的定义。一定要注意变量是有范围的,单字节、双字节还是四字节,有符号还是无符号,不要出现加完变成负数的情况。再就是变量使用前一定要声明,每个变量的作用域是花括号{}的范围。C语言里本来是没有字符串类型的。标准C里有的是“字符类型的数组”,MFC里有专门的CString是个类,STL里才有了std::string类型,严格说起来也是类。
      二是数组。C语言里的数组没有PHP那么灵活,想对数组,尤其是结构体数组进行操作比较麻烦。数组唯一的下标只有序号。好在后来C++有了STL库,可以用map或者list之类的代替数组。
      三是跟指针有关的运算符号。*,&,->,.这几个,尤其是->和.,可能跟你原来的习惯不太一致。

      C++在我看来,比C语言多出来的就是个类。C++所谓的封装、继承和多态都是基于类的。
      封装的话,PHP里就有类,我就不多说了。
      C++的继承可以无限下去,子类继承父类,父类继承爷爷类。孙子类可以直接调用爷爷类的方法、访问爷爷类的成员。C++允许纯虚函数的存在,也就是父类写个函数,只有声明,然后每个不同的子类对该函数进行不同的实现。好处是外部调用的时候,方法是统一的。父类的函数如果声明成虚方法,那么子类中是可以对这个函数进行重写的。这时外面调用函数,调的是子类的方法。
      多态指的是同一个函数名,可以写成不同的参数声明,然后走不同的逻辑。

      C和C++的难点是指针。C语言里指针指万物,指针可以是变量,可以是类,可以是函数,也可以是另一个指针。也因为这个,所以C语言是不负责内存回收的。简单的说,你写了new,就一定要写delete。

      其实现在玩C++,路子已经挺窄的了,基本就是Windows平台。在嵌入式领域C++还不如纯C吃得开。
      在Window上就不能不说MFC。要学消息机制、线程和进程间通信、信号量。

      你所担心的应该是编译和链接。如果用Visual Studio,那么大多数事情IDE已经帮你做了。用VS Code或者Eclipes才要自己手动配,确实挺麻烦的。C++的编译和链接是两回事。编译是负责你的逻辑对不对,链接是找你要用的东西都有没有。链接是比编译麻烦得多的事情,因为涉及到不同的机器不同的环境。链接分为静态链接和动态链接。静态链接就是把所有的功能都放在一个EXE里,这样编出来的东西比较大,但能保证一定好用。动态链接则是exe比较小,用到“别人的”东西的时候,让系统帮着找,所以有可能找不到或者版本不对。
      有时候别人的代码你自己拿来编,编不过,就是库出了问题。相对路径不对,或者干脆写了绝对路径什么的。到现在的Win10更麻烦,有时候Win10小版本不一致都会出链接错误,非常烦人。

      高级的用法还有一个模板类。需要先建立抽象的模型,然后把类传进函数里做参数。我非常不喜欢用,因为编译器无法识别出模板类的错误,只有到运行的时候才能发现。这种用法有一点点像JS。

      书的话,还是最基本的《C++ Primer》吧,剩下的完全靠实战。

      1. 呃,怎么说呢,你写的这些我或多或少都知道。写PHP和JS的时候还经常有手动清理变量的习惯。
        我想学编译类主要是想接触用引擎做游戏。目前靠谱的引擎都把其他语言去掉了,只有C和C++以及C#经久不衰(框架的性能问题和维护成本),以前还有unrealscript和unityscript,都被淘汰了。PHP局限性非常大,JS的框架只剩cococs(虽有良好的跨平台能力但性能特别差)。
        如果我要接触的话大概是会在GUI走QT系的,主要在Linux下混。
        我现在是用Atom的,近期打算换成VSC。Atom的维护的确在微软收购GitHub之后变得很差,常用的几个插件维护者都改去做VSC插件的。

        1. QT我只是改过,没自己写过东西。感觉也就是个message机制。
          Atom我用过不到半年就放弃了,确实没有VSC好用。

          1. Atom从2015年一直用到现在,用了4年。我在几个公司都发现自己是唯一用Atom的,我也没遇到过其他人总抱怨的问题,默认设置我也没改过,相当不清楚为什么放在别人电脑上就不能用。

你好,新朋友。留言前请先填写昵称邮箱