C++中的類可以簡單看作是結構體的升級版,但是在類中成員不僅可以是變數也可以是函數。變數可以稱作類的屬性,函數可以稱爲類的方法。
範例:
class stduent
{
public:
int id;//成員之1
int age;//成員之2
void test(void);//成員之3,函數
private:
int score;//成員之4
};
建立的方法類似結構體的定義方法,關鍵字 public 確定了類的成員的存取屬性。在類物件作用域內,公共成員在類的外部是可存取的。也可以指定類的成員爲 private 或 protected,表明成員只能在類的內部進行存取。
物件是類的範例化,使用物件可以存取類的成員,建立方法有兩種。
可以使用下面 下麪方法直接建立:
//類名 物件名
student stdent1;//建立一個student類的物件student1
或者使用new方法在堆中建立:
student *student1 = new student;
使用這種方法建立的物件,可以使用delete
方法刪除,刪除後就可以釋放堆中的記憶體。如:
delete student1;
成員函數也是類的成員,可以在類中直接定義,也可以在類中宣告,在外部定義。
在類中定義:
class student
{
public:
int id;//成員之1
int age;//成員之2
void test(void){//成員函數
printf("internal class\n");
}
private:
int score;//成員之3
};
在外部定義時,需要使用範圍解析運算子 :: 表明函數所屬的類,格式如下:
返回值 類名::函數名(參數)
class student
{
public:
int id;//成員之1
int age;//成員之2
void test(void);//宣告成員函數
private:
int score;//成員之3
};
void student::test(void)//成員函數定義
{
printf("external class\n");
}
使用物件可以在外部存取類的public成員,使用普通方法建立的物件使用**(.)存取,使用指針new建立的物件則使用(->)**存取,與C語言中的結構體成員存取方法類似。
注意:預設無修飾符的類成員是private或者protected的。
#include <iostream>
using namespace std;
class student
{
public:
int id;//成員之1
int age;//成員之2
void test(void);
private:
int score;//成員之3
};
//成員函數
void student::test(void)
{
printf("class function!\n");
}
int main()
{
student student1;
student *student2 = new student;
//存取類的成員變數
student1.id = 20;
student2->id = 21;
//存取類的成員函數
student1.test();
student2->test();
cout << "student1.id = " << student1.id << endl;
cout << "student2->id = " << student2->id << endl;
cout << "Hello World!" << endl;
return 0;
}
在一個類中,可以定義同名但函數參數不相同的成員函數,當外部呼叫時,會自動根據呼叫函數時傳遞的參數,來選擇對應的函數進行呼叫。這些函數就是過載函數,C++的這種特性稱做過載特性。
在student類中定義三個同名的test
函數,每個函數的參數均不相同,呼叫時傳遞不同參數呼叫不同函數。
#include <iostream>
using namespace std;
class student
{
public:
int id;//成員之1
int age;//成員之2
void test(char Chinese[]);
void test(int Math);
void test(float Physic);
private:
int score;//成員之3
};
void student::test(char Chinese[])
{
cout << "Get Chinese Score!" << endl;
}
void student::test(int Math)
{
cout << "Get Math Score!" << endl;
}
void student::test(float Physic)
{
cout << "Get Physic Score!" << endl;
}
int main()
{
student student1;
char c[] = "Chinese";
student1.test(c);
student1.test(100);
float n=100.0;
student1.test(n);
cout << "Hello World!" << endl;
return 0;
}
執行結果:
建構函式是類的一個特殊成員函數,當使用類建立一個物件時,就會執行這個類別建構函式。
建構函式的名字與類的名字完全一致,建構函式可以帶參數,但無返回值。
無參數的建構函式:
class student
{
public:
int id;//成員之1
int age;//成員之2
void SetScore(int Setscore);//成員函數
int GetScore(void);//成員函數
student();//建構函式
private:
int score;//成員之3
};
//建構函式,名字需要與類相同
student::student(){
cout << "student Object is created!" << endl;
}
主函數:
int main()
{
student student1;//建立物件時會呼叫建構函式
cout << "Hello World!" << endl;
return 0;
}
結果:
帶參數的建構函式:
預設的建構函式沒有參數, 需要時可以給建構函式設定參數,傳遞給類的成員進行初始化操作。需要才建立物件時,傳遞參數,格式如下:
類名 物件名(參數列表);
如下通過建構函式對類的私有成員score
進行賦值操作:
#include <iostream>
using namespace std;
class student
{
public:
int id;//成員之1
int age;//成員之2
void SetScore(int Setscore);//成員函數
int GetScore(void);//成員函數
student(int Score);//建構函式
private:
int score;//成員之3
};
//建構函式
student::student(int Score){
cout << "student Object is created!" << endl;
score = Score;
}
//函數功能:設定成績score
void student::SetScore(int Setscore)
{
score = Setscore;
}
//函數功能:獲取成績score
int student::GetScore(void)
{
return score;
}
int main()
{
student student1(100);//建立物件時,使用建構函式傳遞參數score的值爲100
cout << "Init score = " << student1.GetScore() << endl;//列印score
student1.SetScore(99);//重新設定score的值
cout << "Set score = " << student1.GetScore() << endl;//列印score
cout << "Hello World!" << endl;
return 0;
}
輸出結果:
解構函式與建構函式相反,當類的物件被刪除時執行,同樣沒有返回值,但是與建構函式不同,解構函式不可以帶參數。
解構函式的名字也與類的名字相同,但是需要在函數名前加~符號。
解構函式可以在跳出程式(比如關閉檔案、釋放記憶體等)前進行釋放資源等操作。
主函數中使用類建立物件時會呼叫建構函式,程式執行結束物件被刪除時會呼叫解構函式:
#include <iostream>
using namespace std;
class student
{
public:
int id;//成員之1
int age;//成員之2
student(int Score);//建構函式
~student(void);//解構函式
private:
int score;//成員之3
};
//建構函式
student::student(int Score){
cout << "student Object is created!" << endl;
score = Score;
}
student::~student(void)
{
cout << "student Object is deleted!" << endl;
}
int main()
{
student student1(100);
cout << "Hello World!" << endl;
return 0;
}
執行結果:
物件導向中繼承是一個非常重要的部分。類的繼承就是在一箇舊的類基礎上定義一個新的類,這個新類稱爲子類,舊類稱爲父類別。子類可以擁有父類別部分或全部的屬性和方法,這就是繼承。新生成的子類可以在父類別的基礎上修改父類別的成員,可以新增更多的屬性、方法,可以大大開發提高效率。
繼承格式:
class 子類: 繼承型別(public/private/protected) 父類別
繼承型別:類的成員有public、private、protected三種類型,繼承時可以選擇將父類別的public和protected成員(private成員不可繼承)繼承爲子類的public、private、protected成員。所以有三種繼承型別:
定義一個Animal動物類,再定義一個Dog類(公有繼承自Animal類),Dog的物件可以獲得Animal的public和protected成員。
子類Dog可以修改父類別Animal的已有成員name、Eat(),同時繼承了父類別的Drink()成員,新增了Bark()。
#include <iostream>
using namespace std;
//animal類
class Animal
{
public:
char *name="--->I am an animal<---";
void Eat(void);//成員函數(技能1):吃
void Drink(void);//成員函數(技能2):喝
private:
void AniamlPrint(void);
};
//吃
void Animal::Eat(void)
{
cout << "I can eat.." << endl;
}
//喝
void Animal::Drink(void)
{
cout << "I can drink.." << endl;
}
//Dog類繼承自Animal類public部分,公有繼承
class Dog: public Animal
{
public:
char *name="--->I am a dog<---";
void Eat(void){
cout << "I can eat!" << endl;
}
void Bark(void);//吠,Dog的成員
};
//吠
void Dog::Bark(void)
{
cout << "I can bark.." << endl;
}
int main()
{
Animal animalA;
Dog WangWang;
cout << animalA.name << endl;
animalA.Eat();
animalA.Drink();
cout << WangWang.name << endl;
WangWang.Eat();
WangWang.Drink();
WangWang.Bark();
return 0;
}
執行結果:
虛擬函式也是類的成員函數,需要在函數名前加上virtual關鍵字宣告爲虛擬函式。
定義虛擬函式的目的:爲了允許用父類別的指針來呼叫子類的這個函數。
可以用下面 下麪這個例子進行說明:
//來自菜鳥教學
#include <iostream>
using namespace std;
class A{
public:
virtual void foo()
{
std::cout << "A::foo() is called" << endl;
}
};
class B: public A
{
public:
void foo()
{
std::cout << "B::foo() is called" << endl;
}
};
int main(int argc, char *argv[]) {
A *a = new B();
a->foo();
return 0;
}
*A a = new B();這條語句的意思是建立一個A型別的指針,指向B類的物件。根據指針的指向關係,使用a存取foo()函數自然會呼叫B類的foo(),因爲a指向的是B的物件。這樣就實現了使用父類別(型別爲A)的指針存取子類(B)的函數。
結果:
純虛擬函式同樣使用virtual關鍵字進行修飾,但純虛擬函式只在父類別中進行宣告,沒有函數的定義(功能實現)。當其他的子類繼承這個父類別時,都必須實現這個純虛擬函式。
定義純虛擬函式的目的:實現一個介面,起到一個規範的作用,規範繼承這個類的程式設計師必須實現這個函數。
#include <iostream>
using namespace std;
class A{
public:
virtual void foo()=0;//純虛擬函式,只有宣告,無定義
};
class B: public A//B繼承自A
{
public:
void foo()//子類B中進行純虛擬函式的定義
{
std::cout << "foo() is Pure virtual function!" << endl;
}
};
int main() {
B b;
b.foo();
return 0;
}
結果: