前言
這是一篇C#開發重新學習C++的體驗文章。
作為一個C#開發為什么要重新學習C++呢?因為在C#在很多業務場景需要調用一些C++編寫的COM組件,如果不了解C++,那么,很容易。。。注定是要被C++同事忽悠的。
我在和很多C++開發者溝通的時候,發現他們都有一個非常奇怪的特點,都很愛裝X,都覺得自己技術很好,還很愛瞧不起人;但如果多交流,會發現更奇怪的問題,他們幾乎都不懂代碼設計,面向對象和業務邏輯的代碼寫的也都很爛。
所以,這次重溫C++也是想了解下這種奇異現象的原因。
C++重溫
首先打開VisualStudio,創建一個C++的Windows控制臺應用程序,如下圖:

圖中有四個文件,系統默認為我打開了頭文件和源文件的文件夾。
系統這么做是有意義的,因為剛學習時,外部依賴項,可以暫時不用看,而資源文件夾是空的,所以我們只專注這兩個文件夾就可以了。
作為一個C#開發,我對C++就是一知半解,上學學過的知識也都忘記的差不多了,不過,我知道程序入口是main函數,所以我在項目里先找擁有main函數的文件。
結果發現ConsoleTest.cpp文件里有main函數,那么,我就在這個文件里開始學習C++了,而且它的命名和我項目名也一樣,所以很確定,它就是系統為我創建的項目入口文件。
然后我打開ConsoleTest.cpp文件,定義一個字符串helloworld,準備在控制臺輸出一下,結果發現編譯器報錯。。。只好調查一下了。
調查后得知,原來,c++里沒有string類型,想使用string類型,只能先引用string的頭文件,在引用命名空間std,如下:
頭文件
頭文件到底是什么呢?
頭文件,簡單來說就是一部分寫在main函數上面的代碼。
比如上面的代碼,我們將其中的引用頭文件和使用命名空間的代碼提取出來,寫進pch.h頭文件;然后,我們得到代碼如下圖:
pch.h頭文件:

ConsoleTest.cpp文件:

也就是說,頭文件是用來提取.cpp文件的代碼的。
呃。。。好像頭文件很雞肋啊,一個文件的代碼為什么要提取一部分公共的?寫一起不就好了!為什么要搞個文件來單獨做,多傻的行為啊!
好吧,一開始我也的確是這么想的。
后來我發現,頭文件,原來并不是單純的提取代碼,還是跨文件調用的基礎。
也就是說,ConsoleTest.cpp文件,想調用其他Cpp文件的變量,必須通過頭文件來調用。
比如,我新建一個test.cpp和一個test.h文件。
然后我在test.cpp中,定義變量test=100;如下:
#include "pch.h"#include "test.h"int test = 100;
接著我在test.h文件中再聲明下test變量,并標記該變量為外部變量,如下。
現在,我在回到ConsoleTest.cpp文件,引用test.h文件;然后我就可以在ConsoleTest.cpp文件中使用test.cpp中定義的test變量了,如下:
如上述代碼所示,我們成功的輸出了test變量,其值為100。
到此,我們應該了解到了,頭文件的主要作用應該是把被拆散的代碼,扭到一起的紐帶。
----------------------------------------------------------------------------------------------------
PS:我在上面引用字符串頭文件時,使用的引用方法是【#include <string>】;我發現,引用該頭文件時,并沒有加后綴.h;我把后綴.h加上后【#include <string.h>】,發現編譯依然可以通過。
簡單的調查后得知,【#include <string>】是C++的語法,【#include <string.h>】是語法。因為C++要包含所有C的語法,所以,該寫法也支持。
Cin與Cout
Cin與Cout是控制臺的輸入和輸出函數,我在測試時發現,使用Cin與Cout需要引用iostream頭文件【#include <iostream>】,同時也要使用命名空間std。
在上面,我們提到過,使用字符串類型string時,需要引用頭文件string.h和使用命名空間std,那么現在使用Cout也要使用命名空間std。這是為什么呢?
只能推斷,兩個頭文件string.h和iostream.h在定義時,都定義在命名空間std下了。而且,通過我后期使用,發現還有好多類和類型也定義在std下了。
對此,我只能說,好麻煩。。。首先,缺失基礎類型這種事,就很奇怪,其次不是一個頭文件的東西,定義到一個命名空間下,也容易讓人混亂。
不過,對于C++,這么做好像已經是最優解了。
----------------------------------------------------------------------------------------------------
PS:Cin與Cout是控制臺的輸入和輸出函數,開始時,我也不太明白,為什么使用這樣兩個不是單詞的東西來作為輸入輸出,后來,在調查資料時,才明白,原來這個倆名字要拆開來讀。
讀法應該是這樣的C&in和C&out,這樣我們就清晰明白的理解了該函數了。
define,typedef,指針,引用類型,const
define
首先說define,define在C++里好像叫做宏。就定義一個全局的字符串,然后再任何地方都可以替換,如下:
也就是說,define定義的宏,在C++里就是個【行走的字符串】,在編譯時,該字符串會被替換回最初定義的值。這。。。這簡直就是編譯器允許的bug。。。
不過,它當然也有好處,就是字符串更容易記憶和理解。但是說實話,定義一個枚舉一樣好記憶,而且適用場景更加豐富,所以,個人感覺這個功能是有點雞肋,不過C++好多代碼都使用了宏,所以還是需要了解起來。
typedef
typedef是一個別名定義器,用來給復雜的聲明,定義成簡潔的聲明。
如上述代碼所示,我定義了一個結構體kiba_Org,如果我要用kiba_Org聲明一個變量,我需要這樣寫【struct kiba_Org korg】,必須多寫一個struct。
但我如果用typedef給【struct kiba_Org korg】定義一個別名kiba,那么我就可以直接拿kiba聲明變量了。
呃。。。對此,我只能說,為什么會這么麻煩!!!
以為這就很麻煩了嗎?NO!!!還有更麻煩的。
比如,我想在我定義的結構體里使用自身的類型,要怎么定義呢?
因為在C++里,變量定義必須按照先聲明后使用的【絕對順序】,那么,在定義時就使用自身類型,編譯器會提示錯誤。
如果想要讓編譯器通過,就必須在使用前,先給自身類型定義個別名,這樣就可以在定義時使用自身類型了。
呃。。。好像有點繞,我們直接看代碼。
如上述代碼所示,我們在定義結構體之前,先給它定義了個別名。
那么,變量定義不是必須按照先聲明后使用的【絕對順序】嗎?為什么這里,又在定義前,可以定義別名了呢?這不是矛盾了嗎?
不知道,反正,C++就是這樣。。。就這么 主站蜘蛛池模板: 南投县| 惠州市| 兴宁市| 合水县| 阿克| 万盛区| 长沙市| 茌平县| 崇左市| 平阳县| 鱼台县| 广汉市| 宣威市| 阳信县| 阿荣旗| 临汾市| 岫岩| 龙胜| 仙游县| 施甸县| 山东| 鄂托克旗| 内黄县| 谷城县| 贡觉县| 永济市| 邓州市| 巨野县| 正阳县| 岗巴县| 阳信县| 福州市| 赞皇县| 台东市| 黑水县| 白山市| 齐齐哈尔市| 梨树县| 印江| 水富县| 通江县|