python和C++技術對比

【python】詳解類class的繼承、__init__初始化、super方法:
https://blog.csdn.net/brucewong0516/article/details/79121179
備註:C++以11版本爲基礎,python以python3爲基礎
第一部分.語言的初級運用

python對於數據類型的處理特別靈活,使用python寫的類是天然的模板類,使用python寫的函數是天然的模板函數,不過這也產生了很多的陷阱。我個人感受而言,python是一種使用簡單,但是理解上比較難的語言,因爲它的很多功能都已經封裝好了,從表面上看不出它實現的原理。但是C++是一種使用難但是理解起來簡單的語言,是因爲使用C++很多的類型是需要自己去構建的。

一、內置類型
Python的內置類型有:
Python的數據類型主要要分清楚類型的不可變性和可變性的特質(一度認爲這個不太好理解。)
數字(包括整數、分數、小數、浮點數,具有不可變性);
字符串(單引號‘str’和雙引號“str”都可以,具有不可變性);
集合({‘set’,‘set’},集合具有唯一性,就是集合裏面的元素只能出現一次,具有不可變性);
元祖((tuple),可以任數據類型意嵌套,具有不可變性);
列表([list],可以任意數據類型進行嵌套,具有可變性,與元祖最大的區別就是它具有可變性);
字典(dir{‘key’:‘’},字典的鍵值對,值可以進行任意數據類型嵌套,具有可變性,但沒有順序性);
其他數據類型:None、布爾型。

C++的數據類型:
C++數據類型不是其編程的重點,在STL庫中可以重點關注string、vector等,包括STL中的各種容器,自定義的類都可以看做是一種數據類型(個人認爲);還有需要注意的是C-風格字符串和string類字符串的區別。
C++數據格式還有結構struct、共用體union、枚舉enum、

二、函數傳值、傳引用和傳指針的一些概念
Python:
1、python中的一個重要思想就是類型屬於對象,而不是變量,變量指向對象,當變量賦給另一個值時,該變量指向另一個對象。
例如:a = 5 變量a指向對象5。
a = 10 變量a指向對象10,對象5因爲沒有其他變量指向它,因此被自動銷燬。
2、python中數據的嵌套使用要注意,特別是可變類型的嵌套使用,一個變量的改變會改變另一個變量的值。也即是python中賦值生成引用,而不是拷貝。
例如:a = [1,2,3]
b = [a,2,3] 此時b=[[1,2,3],2,3]
若a[1]=99 此時b=[[1,99,3],2,3]
3、python函數參數值的傳遞。在參數的傳遞過程中,不可變參數“通過值(如C++中的傳值)”進行傳遞,如數字、字符串。可變參數通過“指針”(如C++中的傳指針或傳引用)進行傳遞可變類型在函數中會改變參數的值,類似於C++中的傳指針或傳引用。
例如:def Change(a,b):
a = 2;
b[0] = ‘spam’
X = 1
L = [1,2]
Change(X,L) 此時X=1不變,L=[‘spam’,2]被改變
因爲整數爲不可變量,當給變量a賦值時,a會指向另外一個對象。
4、函數的參數。C++中主要分爲按值、按指針和按引用傳遞參數;python中分爲按不可變參數和可變參數來進行參數的傳遞。其中python中的參數傳遞更爲靈活,
支持關鍵字參數傳遞(C++不支持):def func(a=1,b=2,c=3)
支持任意個數參數傳遞(C++不支持)def func(arg)(元祖參數) def func(**arg)(字典參數)
Python中萬物皆是對象,竟然可以將函數當做參數進行傳遞;
Python中的keyword-only參數,只能進行關鍵字參數的傳遞,在參數列表中位於
arg之後,例如func(a,*b,c),則c只能使用關鍵字參數進行傳遞

三、有關作用域關鍵詞
在python中,作用域關鍵詞有global、nonlocal
global關鍵詞:代表該模塊的全局變量申明,函數中使用global申明,代表該變量的作用域在是全局變量;
nonlocal關鍵詞(只在opencv3中可以使用):作用與global一樣,只不過nonlocal指的是嵌套中函數的申明,作用域與global不一樣。
lambda表達式:

在C++中,作用域關鍵詞有(靜態存儲持續性)static、(動態存儲持續性)new、(線程存儲持續性)thread_local、自動持續變量(在代碼塊內,無關鍵詞修飾)。重點介紹靜態變量。
靜態變量分爲外部鏈接性(沒有static修飾的全局變量)、內部鏈接性(有static修飾的全局變量)和無鏈接性(有static修飾的局部變量,相對於局部變量在程序巡行階段會一直存在。)三種特性。
1、外部連接性,在其他文件或者是函數內部中如果要使用該變量,應使用使用申明關鍵字extern。用於文件之間各個位置的數據共享。
2、內部連接性,有關鍵字static進行限定,只在本文件中有用。如static int a;此外,內部靜態變量也可以屏蔽外部的同名變量。用於文件內部各個位置的數據共享。
3、無連接性。在函數內部或代碼塊定義的static變量,無連接性,但是始終存在於內存當中。因此若該變量在函數內部,則每次調用都不會對該變量進行初始化,只會在第一次調用時初始化一次。
例如:int add()
{
static int a = 0;
a += 5;
return a;
}
int main()
{
for (int i = 0; i < 5; i++)
{
cout << aadd() << endl;
}
return 0;
}
輸出爲:5,10,15,20,25;

四、迭代器
Python中的迭代器是針對可迭代對象而言的,包括列表、元祖、字符串、文件、字典等。注意:文件是自己的迭代器,其他內置類型不是自己的迭代器。對於本身不是迭代器的類型對象,必須使用iter來啓用迭代,並且支持多次打開迭代器:(下面是手動打開迭代器的方法)
例如:L = [1,2,3]
I = iter(L) I是L的迭代器
自動迭代的方法,使用for循環
例如:for i in L:
Python中迭代協議更多的使用在列表解析的功能中,並且使用列表解析速度非常之快。應該熟練使用列表解析。
例如:L = [1,2,3,4]
K = [x+10 for x in L]
有很多的python內置函數使用到了迭代協議,如range(),map(),zip(),filter()等一些內置函數,返回的都是一個迭代器,但是range()本身不是迭代器。
Python的生成器函數:yield關鍵字。yield關鍵字定義了生成器函數,生成器函數支持迭代協議(即可看做是一個迭代函數)。生成器函數一次只生成一系列值中的一個值。由此還有生成器表達式,其形式和列表解析一樣。但是生成器表達式是括在括號裏面的。值得注意的是,生成器函數和生成器表達式其自身就是迭代器,只支持一次活躍迭代。生成器函數和生成器表達式的作用就是能夠編寫自己的迭代器類型。
例如:G=(x**2 for x in range(5)),G是一個生成器對象,支持迭代協議,可以使用next(G)。

在C++中,STL類型中都有自己內置的迭代器,可以使用內置的迭代器對其進行訪問。作用和使用方法暫時沒有過多的瞭解??
C++迭代器值STL庫中的重要部分,可以將它看做是一種指針,並且能夠進行++、–等操作。迭代器主要的解決的問題是針對不同的容器可以使用同樣的迭代方法進行操作,增加了代碼的重用性。例如STL中的算法就是通過迭代器來處理不同類型的容器的。

第二部分.語言的高級運用
五、面向對象的編程——類的基礎知識
C++的類知識是C++面向對象編程的基礎。C++類的基礎知識包括C++類的構造函數、析構函數、賦值構造函數、賦值運算符重載、類的友元函數與重載的關係、類的轉換函數(將單個值轉換成類需要有相應的類構造函數)等一些基本知識。注意:
1、C++的靜態類成員在使用之前一定要進行初始化,還有靜態類成員函數的使用;
2、構造函數中使用new的一些注意事項,一定要配套的使用析構函數進行釋放;
3、函數的參數和返回值應儘量使用引用傳遞,可以減少副本的生成和銷燬,使運行效率更高;
4、類的運算符重載用於方便類的運算,可以使用友元函數促進運算符重載的開發。

Python中的類也是使用class關鍵字進行定義的。Python中的私有成員和函數是由兩條下劃線__開始的,例如__name就代表私有成員,歧視這是一種僞私有成員,只是被編譯器翻譯成了_classname__name。由一條下劃線開始的是類的保護成員。Python的內存是自動進行管理的,肯定就不需要析構函數了。對於python的複製構造函數,可以考慮使用__copy__和__deep__copy__的方法進行復制或深度複製。
1、python的構造函數__init__(self)、析構函數__del__(self)、靜態變量(靜態變量位於累的全局申明中,並且只有使用類名進行調用纔是靜態變量,可以供所有實例共享)
例如: class base:
Static_num=0 #靜態變量
def init(self):
base.Static_num += 1 #靜態變量的使用

2、python中類的動態變量(如C++中new出來的動態變量)該如何申明與使用??或者說python中有沒有這種動態變量的概念?
3、Python中的運算符重載。C++中運算符重載是使用operator關鍵字和符號的形式進行重載的,python是使用特定的函數名對符號進行重載的。
4、python中不支持函數的重在。因此每個構造函數只能有一個構造函數。但是構造函數可以接收多種類型的和數量的參數,也就實現了構造函數的多態性。

六、面向對象的編程——類的繼承

C++中類的繼承分爲公有繼承、私有繼承和保護繼承。講的就是基類與派生類的故事。
1、派生類要有自己的構造函數,並且派生類構造函數必須使用基類的構造函數(一般使用成員初始化列表的操作)
2、基類指針可以指向派生類,但是派生類指針不能指向基類,同樣的派生類可以複製給基類,但是基類不能複製給派生類。因爲派生類有基類的全部成員,所以可以複製過去;但是基類只有派生類的部分成員,所以不能複製過去。
3、多態公有繼承。派生類的方法重新定義了基類的方法。如果要使用基類指針來調用基類和派生類的方法,這個時候就需要虛函數了。虛函數是根據指針指向的類對象來調用方法的,非虛函數是根據指針的類型來調用方法的。
4、析構虛函數的使用,派生類如果是new出來的,在delete時需要調用對應類的析構函數,這時候就用到了虛析構函數。
5、Protected屬性的成員。帶有protected屬性的成員和成員函數主要是供派生類使用的。基類的protected成員可以供派生類使用,但是不能供外部使用。
6、當派生類使用new進行動態內存分配時,需要單獨爲派生類定義顯示的複製構造函數、析構函數和賦值運算符。派生類的析構函數會自動調用基類的析構函數,所以不需要顯式調用基類的機構函數,只需要delete掉派生類中的new的變量。
7、注意友元函數的繼承問題

七、面向對象的編程——代碼重用
1、包含和私有繼承,一般使用包含的關係。
2、多重繼承,多重繼承可能會造成二義性的情況,可以使用虛基類的方法進行有效避免。
3、模板類,適用於多種類型數據的類。使用template class name{};進行申明。在使用類模板中,要注意指針類數據的通用性。
4、模板類的表達式參數(又叫非類型參數),主要解決的是使建立指定長度的數組更加方便和高效,減少了使用new和delete來進行內存管理的開銷,但是數組長度一旦確定就不能進行改變。
5、模板類可以作爲另一個模板類的成員,作爲對比,一個函數裏面不能定義另一個函數,這是C++的一個特性。
6、模板類和友元函數的使用。

八、面向對象的編程——友元、異常和其他
1、友元類,一個類作爲另一個類的友元。不管是友元函數還是友元類,都是提供一種使外部方法能夠訪問內部數據的方案。例如遙控類和電視機類,遙控類需要能夠訪問電視機類的數據,因此使用遙控類作爲電視機類的友元是一個很好的解決方案。
2、交互式友元類,兩個類互相能訪問對方的成員數據。
3、嵌套類。
4、智能指針。指針在使用過程中很容易忘記delete掉用new生成的內存,智能智能就是一種用來解決這種問題的方案(智能釋放內存)。智能指針的思想是:智能指針是一種模板類,刪除指針的時候回調用其析構函數來釋放內存。使用智能指針需要頭文件包含memory,再進行初始化。
例如:#include
auto_ptr ptr(new int); //一個指向int數據類型的指針
智能指針有auto_ptr , unique_ptr , shared_ptr

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章