C++類的定義和對象


C++類的定義和對象

類的成員變量稱為類的屬性(Property),將類的成員函數稱為類的方法(Method)。在面向對象的編程語言中,經常把函數(Function)稱為方法(Method)。

類的定義
class Student{
public:
    //成員變量
    char *name;
    int age;
    float score;
    void say(){
        cout<<name<<age<<score<<endl;
    }
};

類只是一個模板(Template),編譯后不占用內存空間.

class C++ 中新增的關鍵字,用來定義類。

成員變量和成員函數,它們統稱為類的成員(Member)

創建對象:
Student Lilei;   //創建對象

Student是類名,liLei是對象名。和使用基本類型定義變量的形式類似, 從這個角度考慮,我們可以把 Student 看做一種新的數據類型,把 liLei 看做一個變量。

在創建對象時,class 關鍵字可要可不要

class Student LiLei;  //正確
Student LiLei;  //同樣正確

還可以創建對象數組:

Student allStu[100];
使用對象指針:
Student stu;
//pStu 是一個指針,它指向 Student 類型的數據,通過 Student 創建出來的對象
Student *pStu = &stu;

在堆上創建對象,這個時候就需要使用前面講到的new關鍵字

Student *pStu = new Student;

使用 new 在堆上創建出來的對象是匿名的,沒法直接使用,必須要用一個指針指向它,再借助指針來訪問它的成員變量或成員函數.

對象指針后,可以通過箭頭->來訪問對象的成員變量和成員函數;

兩種創建對象的方式:一種是在棧上創建,形式和定義普通變量類似;另外一種是在堆上使用 new 關鍵字創建,必須要用一個指針指向它,讀者要記得 delete 掉不再使用的對象

C++類的成員變量和成員函數

在定義類的時候不能對成員變量賦值,因為類只是一種數據類型或者說是一種模板,本身不占用內存空間,而變量的值則需要內存來存儲.

類的成員函數也和普通函數一樣,都有返回值和參數列表,它與一般函數的區別是:成員函數是一個類的成員,出現在類體中,它的作用范圍由類來決定;而普通函數是獨立的,作用范圍是全局的,或位於某個命名空間內.

只在類體中聲明函數,而將函數定義放在類體外面,如下圖所示:

class Student{
    public:
    	//成員變量;
    	char *name;
    	int age;
    	float score;
    	//聲明成員函數;
    	void say();
};
//定義成員函數
void Student::say(){
	cout<<name<<"的年齡是"<<age<<",成績是"<<score<<endl;
}

類體內成員函數默認為內聯函數; inline 關鍵詞是多余的;

類體外定義 inline 函數的方式,必須將類的定義和成員函數的定義都放在同一個頭(源)文件中.

C++類成員的訪問權限以及類的封裝

成員訪問限定符
  • public
  • private
  • protected

只能修飾類的成員,不能修飾類,C++中的類沒有共有私有之分

類的內部(定義類的代碼內部):

無論成員被聲明為 public、protected 還是 private, 都是可以互相訪問的,沒有訪問權限的限制.

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

#include<iostream>
using namespace std;
//類聲明
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 Student::setname(char *name){
    m_name=name;
}
void Student::setage(int age){
    m_age=age;
}
void Student::setscore(float score){
    m_score=score;
}

類的聲明和成員函數的定義都是類定義的一部分,在實際開發中,我們通常將類的聲明放在頭文件中,而將成員函數的定義放在源文件中。

類的封裝

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

另外還有一個關鍵字 protected,聲明為 protected 的成員在類外也不能通過對象訪問,但是在它的派生類內部可以訪問,這點我們將在后續章節中介紹,現在你只需要知道 protected 屬性的成員在類外無法訪問即可。

class Student{
private:
    char *m_name;
private:
    int m_age;
    float m_score;
public:
    void setname(char *name);
    void setage(int age);
public:
    void setscore(float score);
    void show();
};

以上代碼完全正確。

C++構造函數

構造函數:特殊的成員函數,它的名字和類名相同,沒有返回值,不需要用戶顯式調用(用戶也不能調用),而是在創建對象時自動執行。

#include <iostream>
using namespace std;

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;
}

void Student::show(){
    cout<<m_name<<m_age<<m_score<<endl;
}
int main(){
    //棧上
    Student stu('name',10,10.1f);//不同於python;
    //堆上
    Student *St = new Student('name',10,10.1f);
}

構造函數的調用是強制性的,一旦在類中定義了構造函數,那么創建對象時就一定要調用,不調用是錯誤的。如果有多個重載的構造函數,那么創建對象時提供的實參必須和其中的一個構造函數匹配;反過來說,創建對象時只有一個構造函數會被調用。

一個類必須有構造函數,要么用戶自己定義,要么編譯器自動生成。一旦用戶自己定義了構造函數,不管有幾個,也不管形參如何,編譯器都不再自動生成。

在棧上創建對象可以寫作Student stu()Student stu,在堆上創建對象可以寫作Student *pstu = new Student()Student *pstu = new Student,它們都會調用構造函數 Student()

[C++中棧和堆上建立對象的區別]

在C++中類的對象建立分為兩種,一種是靜態建立,如A a;另一種是動態建立,如A* p=new A()

靜態建立一個類對象,是由編譯器為對象在棧空間中分配內存,通過直接移動棧頂指針挪出適當的空間,然后在這片內存空間上調用構造函數形成一個棧對象。動態建立類對象,是使用new運算符將對象建立在堆空間中,在棧中只保留了指向該對象的指針。棧是由編譯器自動分配釋放 ,存放函數的參數值,局部變量的值,對象的引用地址等。

其操作方式類似於數據結構中的棧,通常都是被調用時處於存儲空間中,調用完畢立即釋放。堆中通常保存程序運行時動態創建的對象,C++堆中存放的對象需要由程序員分配釋放,它存在程序運行的整個生命期,直到程序結束由OS釋放。

C++構造函數初始化列表(初始化列表是先於構造函數的函數體執行)

使用構造函數初始化列表並沒有效率上的優勢,僅僅是書寫方便,尤其是成員變量較多時,這種寫法非常簡單明了。初始化列表可以用於全部成員變量,也可以只用於部分成員變量。

class Student{
private:
	char *m_name;
	int m_age;
	float m_score;
public:
    Student(char *name, int age, float score);
};
Student::Student(char *name, int age, float score): m_name(name), m_age(age), m_score(score){}

成員變量的初始化順序與初始化列表中列出的變量的順序無關,它只與成員變量在類中聲明的順序有關,如下代碼;

#include<iostream>
using namespace std;
class Demo{
private:
    int m_a;
    int m_b;
public:
    Demo(int b);
};
Demo::Demo(int b): m_b(b), m_a(m_b){
}
//Demo::Demo(int b): m_b(b), m_a(m_b){
//    m_a=m_b;  //m_a 在類中先聲明的
//    m_b=b;
//}

const成員變量只可以初始化列表中初始化

const用於類中成員變量時,將類成員變為只讀屬性(只讀:不能出現在“=”的左邊,但在類中仍可以用一個指針來修改其值。) 所以不可以直接在類的構造函數中初始化const 的成員

const成員要不在定義的時候同時初始化,不能進行賦值,就是在初始化列表中對const成員變量成員初始化

#include<iostream>
using namespace std;
class Demo{
private:
    const int ci;
public:
    Demo(int len);
};

Demo::Demo(int len):ci(len){}

const修飾的局部變量在棧上分配內存空間

const修飾的全局變量在只讀存儲區分配內儲存空間

C++復制構造函數

復制構造函數是構造函數的一種,也稱拷貝構造函數,它只有一個參數,參數類型是本類的引用。

復制構造函數的參數是 const 引用或非 const 引用。 一般使用前者,這樣既能以常量對象(初始化后值不能改變的對象)作為參數,也能以非常量對象作為參數去初始化其他對象。一個類中寫兩個復制構造函數,一個的參數是 const 引用,另一個的參數是非 const 引用也可以的。

默認復制構造函數:不寫復制構造函數,編譯器就會自動生成復制構造函數,其作用是實現從源對象到目標對象逐個字節的復制。

若編寫了復制構造函數,則默認復制構造函數就不存在

#include<iostream>
using namespace std;

class Complex{
private:
    double real;
    double imag;
public:
    Complex(double r, double i):real(r),imag(i){}
    Complex(const Complex &c){//編寫的復制構造函數, 加const 可以使得此函數接受常量對象
        real=c.real;
        imag=c.imag;
    }
};
int main(){
Complex c1(1,2);
Complex c2(c1);
return 0;
}

從習慣上來講,復制構造函數還是應該完成類似於復制的工作為好,在此基礎上還可以根據需要做些別的操作

Complex (Complex c) {...}//造函數不能以本類的對象作為唯一參數,和復制構造函數相混淆
復制構造函數被調用的三種情況
  • 當用一個對象去初始化同類的另一個對象時,會引發復制構造函數被調用
Complex c2(c1);
Complex c2 = c1; //初始化語句,不是賦值語句。賦值語句的等號左邊是一個早已有定義的變量,賦值語句不會引發復制構造函數的調用
  • 函數 F 的參數是類 A 的對象, 當 F 被調用時,類 A 的復制構造函數將被調用(傳給形參的是實參的復制)
  • 函數的返冋值是類 A 的對象,則函數返冋時,類 A 的復制構造函數被調用

C++析構函數

在銷毀對象時自動執行。構造函數的名字和類名相同,而析構函數的名字是在類名前面加一個~符號析構函數(Destructor)也是一種特殊的成員函數,沒有返回值, 在銷毀對象時自動執行。構造函數的名字和類名相同,而析構函數的名字是在類名前面加一個~符號。

注意:析構函數沒有參數,不能被重載,因此一個類只能有一個析構函數。如果用戶沒有定義,編譯器會自動生成一個默認的析構函數。

析構函數的作用並不是刪除對象,而是在對象被銷毀時調用完成一些清理工作。

class A{
private:
    char *p;
public:
    A();
    ~A();
};
A::A(){
    p=new char[10];
}
A::~A(){   //在對象撤銷前對在堆上創建的內存執行釋放
    delete[] p;//若A類沒寫析構函數,則在生成A對象后,new出來的內存空間未清除,可					能造成內存泄露
}

在創建一類的對象數組時,對於每一個數組元素,都會執行缺省的構造函數。同樣,對象數組生命期結束時,對象數組的每個元素的析構函數都會被調用。從前往后構造,從后往前析構。

析構函數的執行時機

  • 在所有函數之外創建的對象是全局對象,它和全局變量類似,位於內存分區中的全局數據區,程序在結束執行時會調用這些對象的析構函數。
  • 在函數內部創建的對象是局部對象,它和局部變量類似,位於棧區,函數執行結束時會調用這些對象的析構函數。
  • new 創建的對象位於堆區,通過 delete 刪除時才會調用析構函數;如果沒有 delete,析構函數就不會被執行。

C++ this指針

thisC++ 中的一個關鍵字,一個 const 指針,它指向當前對象,通過它可以訪問當前對象的所有成員。

this 只能用在類的內部,通過 this 可以訪問類的所有成員,包括 private、protected、public 屬性的。

#include <iostream>
using namespace std;
class Student{
public:
    void setname(char *name);
    void setage(int age);
    void setscore(float score);
    void show();
private:
    char *name;
    int age;
    float score;
};
void Student::setname(char *name){
    this->name = name;
}
void Student::setage(int age){
    this->age = age;
}
void Student::setscore(float score){
    this->score = score;
}

成員函數的參數和成員變量重名,只能通過 this 區分。以成員函數setname(char *name)為例,它的形參是name,和成員變量name重名,如果寫作name = name;這樣的語句,就是給形參name賦值,而不是給成員變量name賦值。而寫作this -> name = name;后,=左邊的name就是成員變量,右邊的name就是形參。

this 雖然用在類的內部,但是只有在對象被創建以后才會給 this 賦值。

  • this 只能在成員函數內部使用,用在其他地方沒有意義,也是非法的。
  • 只有當對象被創建后 this 才有意義,因此不能在 static 成員函數中使用(后續會講到 static 成員)。

this 作為隱式形參,本質上是成員函數的局部變量,所以只能用在成員函數的內部,並且只有在通過對象調用成員函數時才給 this 賦值

C++ static靜態成員

C++中,我們可以使用靜態成員變量來實現多個對象共享數據的目標。靜態成員變量是一種特殊的成員變量,它被關鍵字static修飾

static 成員變量屬於類,不屬於某個具體的對象,即使創建多個對象,static 成員變量,分配一份內存,所有對象使用的都是這份內存中的數據。

示例代碼:

#include<iostream>
using namespace std;
class Student{
public:
    Student(char *name, int age, float score);
private:
    char *name;
    int age;
    float score;
private:
    static int s_total;
};

int Student::s_total=0;//static 成員變量必須在類聲明的外部初始化

Student::Student(char *name, int age, float score){
      	this->name=name;
        this->age=age;
        this->score=score;
    	this->s_total++;
    }
int main(){
    Student::m_total=0;//類訪問靜態成員變量
    Student stu;
    cout<<stu.m_total<<endl;//對象訪問靜態成員變量,錯誤的!!! 訪問權限是private對象無法訪問
    //創建匿名對象
    (new Student("小明", 15, 90)) -> show();
}

注意

  • 一個類中可以有一個或多個靜態成員變量,所有的對象都共享這些靜態成員變量
  • static 成員變量和普通 static 變量一樣,都在內存分區中的全局數據區分配內存,到程序結束時才釋放
  • 靜態成員變量必須初始化,而且只能在類體外進行。
  • 靜態成員變量既可以通過對象名訪問,也可以通過類名訪問,但要遵循 private、protected 和 public 關鍵字的訪問權限限制。當通過對象名訪問時,對於不同的對象,訪問的是同一份內存

C++ static靜態成員函數

在類中,static 除了可以聲明靜態成員變量,還可以聲明靜態成員函數。普通成員函數可以訪問所有成員(包括成員變量和成員函數),靜態成員函數只能訪問靜態成員。

靜態成員函數沒有 this 指針,不知道指向哪個對象,無法訪問對象的成員變量,也就是說靜態成員函數不能訪問普通成員變量,只能訪問靜態成員變量.

#include<iostream>
using namespace std;
class Student{
private:
    static int total_stu;
    char *name;
    int age;
    float score;
public:
    static int get_total_stu();//為了訪問 static成員變量,函數也被聲明為 static
    Student(char *name, int age, float score);
};
int Student::total_stu=0;
Student::Student(char *name, int age, float score){
    this->name=name;
    this->age=age;
    this->score=score;
}
int Student::get_total_stu(){
    return total_stu;
}

C++ const成員函數(常成員函數)

const 成員函數可以使用類中的所有成員變量,但是不能修改它們的值,這種措施主要還是為了保護數據而設置的。const 成員函數也稱為常成員函數。

通常將 get 函數設置為常成員函數。讀取成員變量的函數的名字通常以get開頭,后跟成員變量的名字,所以通常將它們稱為 get 函數

常成員函數需要在聲明和定義的時候在函數頭部的結尾加上 const 關鍵字

  • 函數開頭的 const 用來修飾函數的返回值,表示返回值是 const 類型,也就是不能被修改,
  • 函數頭部的結尾加上 const 表示常成員函數,這種函數只能讀取成員變量的值,而不能修改成員變量的值
#include<iostream>
using namespace std;
class Student{
private:
    char *name;
    int age;
    float score;
public:
    char *get_name() const;
    int get_age() const;
    float get_score const;
};
char* Student::get_name() const{
    return this->name;
}
int Student::get_age() const{
    return this->age;
}
float Student::get_score() const{
    return this->score;
}
//必須在成員函數的聲明和定義處同時加上 const 關鍵字


C++ const對象

C++ 中,const 也可以用來修飾對象,稱為常對象。一旦將對象定義為常對象之后,就只能調用類的 const 成員(包括 const 成員變量和 const 成員函數)

//棧上創建
const  class  object(params);
class const object(params);
//堆上定義
const class *p = new class(params);
class const *p = new class(params);

C++友元函數和友元類(C++ friend關鍵字)

友元(friend)。借助友元(friend),可以使得其他類中的成員函數以及全局范圍內的函數訪問當前類的 private 成員。

友元函數

在類中聲明,但要在前面加 friend 關鍵字,友元函數可以是不屬於任何類的非成員函數,也可以是其他類的成員函數

友元函數可以訪問當前類中的所有成員,包括 public、protected、private 屬性的。

一個類友元函數是一個在此類以外定義,在類中聲明即可,不同於類的成員函數,友元函數無法直接訪問類的成員,必須借助對象。

#include<iostream>
using namespace std;
class Address;//Student類要用到Address類,要提前聲明,不然編譯器會報錯
class Student{
private:
    char * name;
    int age;
    float score;
public:
    Student(char *name,int age,float score);
    friend void show(Student &s);
    friend void Address::show(Address *addr);//只有類正式聲明后才能創建對象,但在提前聲明之后,可以類名定義指向該類型變量的指針變量或引用變量。
};
Student::Student(char *name, int age, float score){
    this->name=name;
    this->age=age;
    this->score=score;
}
void show(Student &s){
    cout<<s->name<<s->age<<s->score<<endl;
}
class Address{
private:
    char *m_province;  //省份
    char *m_city;  //城市
    char *m_district;  //區(市區)
public:
    Address(char *province, char *city, char *district);
    void show(Address *addr);
};


友元類

不僅可以將一個函數聲明為一個類的“朋友”,還可以將整個類聲明為另一個類的“朋友”,這就是友元類。友元類中的所有成員函數都是另外一個類的友元函數

將類 B 聲明為類 A 的友元類,那么類 B 中的所有成員函數都是類 A 的友元函數,可以訪問類 A 的所有成員,包括 public、protected、private 屬性。

#include<iostream>
using namespace std;
class Address;
class Student{
public:
    Student(char *name, int age, float score);
public:
    void show(Address *addr);
private:
    char *m_name;
    int m_age;
    float m_score;
};
class Address{
public:
    Address(char *province, char *city, char *district);
    //聲明Student類是Address類的友元類,這樣Student類定義的對象可以訪問Address類定義的對象中的所有成員;
    friend class Student;
private:
	char *m_province;
    char *m_city;
    char *m_distrcit;
};
Student::Student(char *name, int age, float score):m_name(name),m_age(age),m_score(score){}
Student::show(Address *addr){//由於在類Address的聲明里,聲明了Student為Address的友元類,Student的成員函數訪問Address類的所有成員。
    cout<<addr->m_province<<addr->m_city<<addr->m_score<<endl;
}
Address::Address(char *province, char *city, char *district):m_province(province),m_city(city),m_district(district){}

注意:

  • 友元關系是單向的,A類是B類的友元類(A在B的聲明中安插‘奸細’,但B沒有),則A可以訪問B的所有成員,B卻不能訪問A的所有成員。
  • 友元函數不能繼承。A是B的友元,B是C的友元,A不是C的友元

C++ class和struct區別

C++ 中保留了C語言的 struct 關鍵字,並且加以擴充。在C語言中,struct 只能包含成員變量,不能包含成員函數。而在C++中,struct 類似於 class,既可以包含成員變量,又可以包含成員函數。

class和struct區別:

  • class內的成員默認是private,struct內的成員默認是public的。

  • class的繼承是private的,struct的繼承是public的。

  • class可以用模板,struct不能。

    struct定義類的一個反面教材

#include <iostream>
using namespace std;
struct Student{
    Student(char *name, int age, float score);
    void show();
    char *m_name;
    int m_age;
    float m_score;
};
Student::Student(char *name, int age, float score): m_name(name), m_age(age), m_score(score){ }
void Student::show(){
    cout<<m_name<<"的年齡是"<<m_age<<",成績是"<<m_score<<endl;
}
int main(){
    Student stu("小明", 15, 92.5f);
    stu.show();
    Student *pstu = new Student("李華", 16, 96);
    pstu -> show(); //class默認是private的訪問權限,若用類無法訪問show成員函數。
    return 0;
}

C++ string詳解與字符串詳解

C++ 內置的 string 類處理起字符串很方便,完全可以代替C語言中的字符數組或字符串指針

代碼示例

#include<iostream>
#include<string>
using namespace std;
int main(){
	string s1;//只有定義沒有初始化,編譯器默認指定 "" 空字符串為初始值
    string s2="c plus plus";//s2直接賦值 "c plus plus"
    string s3(5,'s');//調用構造函數構造一個對象"ssssss"
    string s4=s3;//s4通過s3進行初始化
    int s4_len=s4.length(); //返回s4的字符串長度,string ,末尾沒有/0,返回值為字符串真實長度。
    const char*c_str=s4.c_str();//string 類字符串轉換為c風格字符串,返回字符串指針const char*
    FILE *fp = fopen(c,"rt");
    cin>>s1;//輸入字符到s1
    cout<<s1;//輸出s1
    s4[1]='d';//修改string字符串的第二個字符為5.
}

字符串的拼接,增刪改查:

拼接

string 類,使用++=運算符來直接拼接字符串,+支持string和string, string+char 數組,string+char單個字符。

#include<iostream>
#include<string>
using namespace std;
int main(){
    string s1="first ";
    string s2="second ";
    char *s3="third ";
    char s4[]="fourth ";
    char ch='@';
    
    string s5=s1+s2;
    string s6=s1+s3;
    string s7=s1+s4;
    string s8=s1+ch;
    
    cout<<s5<<endl<<s6<<endl<<s7<<endl<<s8<<endl;
    return 0;
}

增刪改查

增:

//原型 string& insert (size_t pos, const string& str);
string a1="123456";
a1.insert(5,"aaa");//在a1第五個字符后插入“aaa”

刪:

//原型 string& erase (size_t pos = 0, size_t len = npos);
string s1, s2, s3;
s1 = s2 = s3 = "1234567890";
s2.erase(5);//刪除第五個字符后的所有字符
s3.erase(5, 3);//刪除第五個字符后3個字符

提取子字符:

//原型 string substr (size_t pos = 0, size_t len = npos) const;
string s1 = "first second third";
string s2;
s2=s1.substr(6,6); //從s1的第6個字符開始提取6個字符

substr() erase() 參數的處理:

  • 如果 pos 越界,會拋出異常;
  • 如果 len 越界,會提取從 pos 到字符串結尾處的所有字符。

查:

find() 函數

兩種原型為:

size_t find (const string& str, size_t pos = 0) const;
size_t find (const char* s, size_t pos = 0) const;

第一個為待查找的子字符串(c---字符串, c++ ---string), 第二個參數是開始查找的位置。

string s1 = "first second third";
string s2 = "second";
s1.find(s2,5);//返回待查找字符串第一次出現的起始下標,若未查找到則返回一個無窮大數值

rfind() 函數:find()函數類似,只是第二個參數是停止查找位置(在pos處停止)

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@@@@@@@@@@@ 筆記小結 @@@@@@@@@@@

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

類的成員有成員變量成員函數兩種。

成員函數之間可以互相調用,成員函數內部可以訪問成員變量。

私有成員只能在類的成員函數內部訪問。默認情況下,class 類的成員是私有的struct 類的成員是公有的

可以用“對象名.成員名”、“引用名.成員名”、“對象指針->成員名”的方法訪問對象的成員變量或調用成員函數。成員函數被調用時,可以用上述三種方法指定函數是作用在哪個對象上的。

對象所占用的存儲空間的大小等於各成員變量所占用的存儲空間的大小之和(如果不考慮成員變量對齊問題的話)。

定義類時,如果一個構造函數都不寫,則編譯器自動生成默認(無參)構造函數和復制構造函數。如果編寫了構造函數,則編譯器不自動生成默認構造函數。一個類不一定會有默認構造函數,但一定會有復制構造函數。

任何生成對象的語句都要說明對象是用哪個構造函數初始化的。即便定義對象數組,也要對數組中的每個元素如何初始化進行說明。如果不說明,則編譯器認為對象是用默認構造函數或參數全部可以省略的構造函數初始化。在這種情況下,如果類沒有默認構造函數或參數全部可以省略的構造函數,則編譯出錯。

對象在消亡時會調用析構函數。

每個對象有各自的一份普通成員變量,但是靜態成員變量只有一份,被所有對象所共享。靜態成員函數不具體作用於某個對象。即便對象不存在,也可以訪問類的靜態成員。靜態成員函數內部不能訪問非靜態成員變量,也不能調用非靜態成員函數。

常量對象上面不能執行非常量成員函數,只能執行常量成員函數。

包含成員對象的類叫封閉類。任何能夠生成封閉類對象的語句,都要說明對象中包含的成員對象是如何初始化的。如果不說明,則編譯器認為成員對象是用默認構造函數或參數全部可以省略的構造函數初始化。

在封閉類的構造函數的初始化列表中可以說明成員對象如何初始化。封閉類對象生成時,先執行成員對象的構造函數,再執行自身的構造函數;封閉類對象消亡時,先執行自身的析構函數,再執行成員對象的析構函數。

const 成員和引用成員必須在構造函數的初始化列表中初始化,此后值不可修改。

友元分為友元函數友元類。友元關系不能傳遞。

成員函數中出現的 this 指針,就是指向成員函數所作用的對象的指針。因此,靜態成員函數內部不能出現 this 指針。成員函數實際上的參數個數比表面上看到的多一個,多出來的參數就是 this 指針。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM