C++ 小結--模板、auto關鍵字、指針

寫在前面

之前學過完整的C++,但是學了之後一直沒去用它,忘的也差不多了。掌握C++也是我的計劃之中的事,最近在看MIT mini-cheeath的源代碼,用C++實現的,剛好趁這個時候撿撿C++的知識。以下我不打算很完整的做這個小結。單純是爲了做筆記(其實沒筆記本了),C++的一個特點就是屬性很多,所以要簡化筆記。

小結

1.模板template

有函數模板、類模板l兩種類型。
函數模板:

 template <class 形參名,class 形參名,......> 
 返回類型 函數名(參數列表)

   {

      函數體

   }

知識點:<>內是模板形參,class 是關鍵字。<>內不可爲空,一但聲明瞭模板函數就可以用模板函數的形參名聲明類中的成員變量和成員函數,作用就是用這個模板可以對適應各種數據類型,不用重複聲明函數。例子如下:

template <class T> void swap(T& a, T& b){}

a、b可以是double,也可以是int…這樣就實現了函數的實現與類型無關的代碼
類模板:

template<class  形參名,class 形參名,…>
    class 類名{ ... };

同樣<>裏面是模板形參,不能空。可以在類中使用內置類型的地方都可以使用模板形參名來聲明。例子:

       template<class T> class A
    {
       public: 
       T a;
       T b; 
       T hy(T c, T &d);
       };

在類A中聲明瞭兩個類型爲T的成員變量a和b,還聲明瞭一個返回類型爲T帶兩個參數類型爲T的函數hy。
類模板對象的創建:比如一個模板類A,則使用類模板創建對象的方法爲A m;在類A後面跟上一個<>尖括號並在裏面填上相應的類型,這樣的話類A中凡是用到模板形參的地方都會被int 所代替。當類模板有兩個模板形參時創建對象的方法爲A<int, double> m;類型之間用逗號隔開。
對於類模板,模板形參的類型必須在類名後的尖括號中明確指定。
提醒注意:模板的聲明或定義只能在全局,命名空間或類範圍內進行。即不能在局部範圍,函數內進行,比如不能在main函數中聲明或定義一個模板。

模板的繼承:
模板類的繼承包括四種:
1.(普通類繼承模板類)

1 template<class T>
2 class TBase{
3     T data;
4 ……
5 };
6 class Derived:public TBase<int>{
7 ……
8 };

2.(模板類繼承了普通類(非常常見))

1 class TBase{
2 ……
3 };
4 template<class T>
5 class TDerived:public TBase{
6 T data;
7 ……
8 };

3.(類模板繼承類模板)

1 template<class T>
 2 class TBase{
 3 T data1;
 4 ……
 5 };
 6 template<class T1,class T2>
 7 class TDerived:public TBase<T1>{
 8 T2 data2;
 9 ……
10 };

4.承類模板,即繼承模板參數給出的基類)
——繼承哪個基類由模板參數決定

2.auto關鍵字

它的作用就是,當有一些數據類型很冗長時,用auto聲明自動變量,它會根據你後面賦值是數據什麼數據類型,而給你聲明的變量定義數據類型。

template <typename _Tx,typename _Ty>
void Multiply(_Tx x, _Ty y)
{
    auto v = x*y;
    std::cout << v;
}

若不使用auto變量來聲明v,那這個函數就難定義啦,不到編譯的時候,誰知道x*y的真正類型是什麼呢?剛好和上面模板知識點呼應上。沒被真正使用時,x、y的數據類型時不確定的。
注意點:
auto 變量必須在定義時初始化,這類似於const關鍵字。
定義在一個auto序列的變量必須始終推導成同一類型。例如:

auto a4 = 10, a5 = 20, a6 = 30;//正確
auto b4 = 10, b5 = 20.0, b6 = 'a';//錯誤,沒有推導爲同一類型

如果初始化表達式是引用,則去除引用語義。
如果初始化表達式爲const或volatile(或者兩者兼有),則除去const/volatile語義。
如果auto關鍵字帶上&號,則不去除const語意。
初始化表達式爲數組時,auto關鍵字推導類型爲指針。
若表達式爲數組且auto帶上&,則推導類型爲數組類型。
函數或者模板參數不能被聲明爲auto。
時刻要注意auto並不是一個真正的類型。auto僅僅是一個佔位符,它並不是一個真正的類型,不能使用一些以類型爲操作數的操作符,如sizeof或者typeid。

3.指針

數據類型的定義在內存中,是地址,加數據,比如說,int a = 20; 這段代碼而言,我們知道a是我們定義的變量名,經過編譯器,其實它對應內存上的某個地址,而這個地址對應的內容就是20。a這個變量名其實是爲了讓編程人員更容易記住。其實每個變量名都對應了一個地址。所以指針就引入了。
兩個重要符號

& 取地址符號
* 有兩個作用,一個是取數據,一個是定義指針變量(就是存放地址的變量)。

例子:

char a,*pa;  //這裏定義了兩個變量,一個是字符串類型,一個是指針變量
a = 10;  //給a 賦值
pa = &a;   //pa是指針變量,用於存放地址的,這裏的&a就是把a的地址取出來,賦值給pa
*pa = 20; //*pa就是取內容取數據,pa其實就是存放a 的地址,所以這裏就是將a的數據重新賦值爲20.

上面的註釋就解釋得很清楚了,相信可以很好的理解指針了。。

二級指針:是一種指向指針的指針。我們可以通過它實現間接訪問數據,和改變一級指針的指向問題。

在這裏插入圖片描述
這裏**p就是二級指針,最終 **p等於a 的值。
解釋:**p=&pa ,pa =&a 所以pa就是放a的地址, **p可以看成 *(*p),所以這個時候 **p就是一個存放數據的變量了,&pa就是一個地址 值與指針變量p是一樣的,二級指針就是取值了。結合上面的圖理解。(有點亂,錯了的話,請指點~)
可以通過一級指針,修改 0 級指針(變量)的內容。

  1. 可以通過二級指針,
  2. 修改一級指針的指向。
  3. 可以通過三級指針,修改二級指針的指向。
  4. ·····
  5. 可以通過 n 級指針,修改 n-1
    所有類型的二級指針,由於均指向一級指針類型,一級指針類型大小是 4,所以二級指針的步長也是 4,這個信息很重要。

指針訪問數組: 四種情況瞭解一下

//一
int i, a[] = {3,4,5,6,7,3,7,4,4,6};
for (i = 0; i <= 9; i++)
{
    std::cout << a[i] std::endl;
}
//二
int i, a[] = {3,4,5,6,7,3,7,4,4,6};
for (i = 0; i <= 9; i++)
{
std::cout << *(a+i) << std<<endl;; // 要知道,a[],的第一個地址是a,後面的地址就在加上對應數據類型所佔字節大小
}
//三
int i, *pa, a[] = {3,4,5,6,7,3,7,4,4,6};
pa = a; /*請注意數組名 a 直接賦值給指針 pa*/
for (i = 0; i <= 9; i++)
{
 std::cout <<  pa[i] << std::endl;
}
//四
int i, *pa, a[] = {3,4,5,6,7,3,7,4,4,6};
pa = a;
for (i = 0; i <= 9; i++)
{
   std::cout <<  *(pa+i) << std::endl;
}
//五
int i, *pa, a[] = {3,4,5,6,7,3,7,4,4,6};
pa = a;
for (i = 0; i <= 9; i++)
{
printf("%d\n", *pa);
pa++; /*注意這裏,指針值被修改*/ //其實上面的指針是指針變量,而 數組名只是一個指針常量。不能用a++,a是數組名
}

指針數組,一個全是指針變量:char * pArray[10]
這個數組裏面全都是指針變量,全部都是存放地址的變量。

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