參考: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;
}