天天看點

努力學習c++的一天(九)

參考:http://c.biancheng.net/cpp/biancheng/view/2971.html

參考:https://ruochen.blog.csdn.net/article/details/90719951?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromBaidu-1.control&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromBaidu-1.control

1. 構造函數怎麼寫

首先,當類被執行個體化後,會自動調用構造函數,由構造函數完成對象的初始化工作,構造函數的作用:初始化對象的資料成員;

是以,構造函數中的内容:初始化對象成員(包括public、private);

class Student{

private:

char *m_name;

int m_age;

float m_score;

public:

//聲明構造函數

Student(char *name, int age, float score);

//聲明普通成員函數

void show();

};

//定義構造函數

Student::Student(char *name, int age, float score){

m_name = name;

m_age = age;

m_score = score;

}

//采用參數初始化表,成員變量的指派順序由它們在類中的聲明順序決定,初始化 const 成員變量的唯一方法就是使用參數初始化表。

Student::Student(char *name, int age, float score): m_name(name), m_age(age), m_score(score){

//TODO:

}

在棧上建立對象時,實參位于對象名後面,例如

Student stu("小明", 15, 92.5f)

;在堆上建立對象時,實參位于類名後面,例如

new Student("李華", 16, 96),

調用沒有參數的構造函數也可以省略括号。

構造函數必須是 public 屬性的,否則建立對象時無法調用。

  • 不管是聲明還是定義,函數名前面都不能出現傳回值類型,即使是 void 也不允許;
  • 函數體中不能有 return 語句。

構造函數是允許重載的。一個類可以有多個重載的構造函數,建立對象時根據傳遞的實參來判斷調用哪一個構造函數。

2. 命名空間怎麼寫

為了解決合作開發時的命名沖突問題,C++ 引入了命名空間(Namespace)

namespace name{

    //variables, functions, classes

}

使用變量、函數時要指明它們所在的命名空間。

Li :: fp = fopen("one.txt", "r"); //使用小李定義的變量 fp

Han :: fp = fopen("two.txt", "rb+"); //使用小韓定義的變量 fp

不建議全局使用 using namepace ×,可能會引起問題:增加了命名沖突的風險,但是可以局部使用,例如:在 main() 函數中聲明命名空間 std,它的作用範圍就位于 main() 函數内部,如果在其他函數中又用到了 std,就需要重新聲明

#include <iostream>

void func(){
    //必須重新聲明
    using namespace std;
    cout<<"http://c.biancheng.net"<<endl;
}

int main(){
    //聲明命名空間std
    using namespace std;
   
    cout<<"C語言中文網"<<endl;
    func();

    return 0;
}      

不同的.h中可以使用相同名字的namespace嗎?  可以,會自動合并為一個名字空間,可以了解為追加

3. 常用的頭檔案

  • #include<iostream>    使用輸入輸出時
  • #include <string>     //字元串類

4. 記憶體配置設定

在C語言中,動态配置設定記憶體用 malloc() 函數,釋放記憶體用 free() 函數;C++中使用new 和 delete:new 用來動态配置設定記憶體,delete 用來釋放記憶體。

int *p = new int;  //配置設定1個int型的記憶體空間
delete p;  //釋放記憶體      
int *p = new int[10];  //配置設定10個int型的記憶體空間
delete[] p;      

通常 new 和 delete、new[] 和 delete[] 操作符應該成對出現

5. 為什麼會有内聯函數?

函數調用是有時間和空間開銷的。如果函數體代碼比較多,需要較長的執行時間,那麼函數調用機制占用的時間可以忽略;如果函數隻有一兩條語句,那麼大部分的時間都會花費在函數調用機制上,這種時間開銷就就不容忽視。

指定内聯函數的方法很簡單,隻需要在函數定義處增加 inline 關鍵字。一般隻将那些短小的、頻繁調用的函數聲明為内聯函數。在類體中定義的成員函數會自動成為内聯函數,在類體外定義的不會。

  • //内聯函數,交換兩個數的值
  • inline void swap(int *a, int *b){
  •     int temp;
  •     temp = *a;
  •     *a = *b;
  •     *b = temp;
  • }

6. 建立類和對象

c++一般在 .h檔案中建立類,因為類隻是一個模闆(Template),編譯後不占用記憶體空間,是以在定義類時不能對成員變量進行初始化,因為沒有地方存儲資料。隻有在建立對象以後才會給成員變量配置設定記憶體,這個時候就可以指派了。

通常将類的聲明放在頭檔案中,而将成員函數的定義放在源檔案中。

兩種建立對象的方式:一種是在棧上建立,

Student stu;

Student *pStu = &stu;

另外一種是在堆上建立,

Student *pStu = new Student;

delete pStu; //删除對象      

棧記憶體是程式自動管理的,不能使用 delete 删除在棧上建立的對象;堆記憶體由程式員管理,對象使用完畢後可以通過 delete 删除。

7. 通路權限

在類的内部(定義類的代碼内部,定義類的.h和.cpp),無論成員被聲明為 public、protected 還是 private,都是可以互相通路的,沒有通路權限的限制。

在類的外部(定義類的代碼之外),隻能通過對象通路成員,并且通過對象隻能通路 public 屬性的成員,不能通路 private、protected 屬性的成員。

成員變量大都以

m_

開頭,這是約定成俗的寫法,不是文法規定的内容。以

m_

開頭既可以一眼看出這是成員變量,又可以和成員函數中的形參名字區分開。

//類的聲明

class Student{

private: //私有的

   char *m_name;

   int m_age;

   float m_score;

public: //共有的

   void setname(char *name);

   void setage(int age);

   void setscore(float score);

   void show();

};

根據C++軟體設計規範,實際項目開發中的成員變量以及隻在類内部使用的成員函數(隻被成員函數調用的成員函數)都建議聲明為 private,而隻将允許通過對象調用的成員函數聲明為 public。

給成員變量指派的函數通常稱為 set 函數,它們的名字通常以

set

開頭,後跟成員變量的名字;讀取成員變量的值的函數通常稱為 get 函數,它們的名字通常以

get

開頭,後跟成員變量的名字。

除了 set 函數和 get 函數,在建立對象時還可以調用構造函數來初始化各個成員變量

8. 析構函數

析構函數沒有參數,不能被重載,是以一個類隻能有一個析構函數。

在所有函數之外建立的對象是全局對象,它和全局變量類似,位于記憶體分區中的全局資料區,程式在結束執行時會調用這些對象的析構函數。

在函數内部建立的對象是局部對象,它和局部變量類似,位于棧區,在局部函數執行結束時會調用這些對象的析構函數。

new 建立的對象位于堆區,通過 delete 删除時才會調用析構函數;如果沒有 delete,析構函數就不會被執行。

9. this指針

this 是 const 指針,this 隻能在成員函數内部使用,用在其他地方沒有意義,也是非法的

10. 靜态成員變量和靜态成員函數

使用靜态成員變量來實作多個對象共享資料的目标,就相當于類中的全局變量;

static 成員變量必須在類聲明的外部初始化,具體形式為:

type class::name = value;

static 成員變量既可以通過對象來通路,也可以通過類來通路

靜态成員函數隻能通路靜态成員,靜态成員函數與普通成員函數的根本差別在于:普通成員函數有 this 指針,可以通路類中的任意成員;而靜态成員函數沒有 this 指針,隻能通路靜态成員(包括靜态成員變量和靜态成員函數)。

11. const關鍵字

const 可以用來修飾成員變量、成員函數以及對象。如果你不希望某些資料被修改,可以使用

const

關鍵字加以限定。

const 成員函數可以使用類中的所有成員變量,但是不能修改它們的值;常成員函數需要在聲明和定義的時候在函數頭部的結尾加上 const 關鍵字

class Student{      

public:

Student(char *name, int age, float score);

void show();

//聲明常成員函數

char *getname() const;

int getage() const;

float getscore() const;

private:

char *m_name;

int m_age;

float m_score;

};

//定義常成員函數

char * Student::getname() const{

return m_name;

}

12. friend友元函數和友元類

在目前類以外定義的、不屬于目前類的函數也可以在類中聲明,但要在前面加 friend 關鍵字,這樣就構成了友元函數。

友元函數不同于類的成員函數,在友元函數中不能直接通路類的成員,必須要借助對象。

class Student{

public:

Student(char *name, int age, float score);

public:

friend void show(Student *pstu); //将show()聲明為友元函數

private:

char *m_name;

int m_age;

float m_score;

};

//非成員函數

void show(Student *pstu){

cout<<pstu->m_name<<"的年齡是 "<<pstu->m_age<<",成績是 "<<pstu->m_score<<endl;

}