1、函數重寫(覆寫)
- 定義:子類中實作了一個與父類的成員函數原型完全相同的函數,即為重寫。
- 例子1:下面的代碼中定義了Animal父類和Dog子類,其中都定義了void info()函數,Dog類中的void info()函數重寫(覆寫)了父類了中的info函數,是以在main函數中調用Dog類的info函數時,會調用子類的info函數,即重新寫了該函數,或稱之為覆寫了父類的info函數。
#include<iostream>
using namespace std;
//父類
class Animal
{
protected:
char animalName[30];
int height;
public:
Animal(char* name, int h)
{
strcpy_s(animalName, name);
height = h;
}
void info()
{
cout << "I am an animal" << endl;
cout << "My name is " << animalName <<", height: "<<height << endl;
}
};
//子類
class Dog :public Animal
{
private:
char voice[30];
public:
Dog(char* name, int h, char* v) :Animal(name, h)
{
strcpy_s(voice, v);
}
void info()
{
cout << "I am a dog" << endl;
cout << "My name is " << animalName << ", height: " << height << endl;
}
};
int main()
{
Animal a("cat", 20);
Dog d("dog", 40, "wang");
d.info();
system("pause");
return 0;
}
實驗結果:
I am a dog
My name is dog, height: 40
為了調用父類的info函數,可以采用 子類對象名.父類名::函數名 形式,如: d.Animal::info();
2、虛函數
- 定義:通過virtual關鍵字将類的成員函數定義為虛函數。一般是将父類中與子類函數原型完全相同的成員函數定義為虛函數。
- 作用:(1)通過使用父類的指針或引用指向子類時,指針或引用可以向下調用子類的函數。(2)實作多态。
- 例子2:修改例子1父類(Animal類)中的info函數為虛函數。在主函數中,定義了一個父類類型的指針,它指向了子類對象,當調用info函數時,調用的是子類的info函數,實作了向下轉型。同理,通過引用的方式,也可以調用子類的成員函數info。
-
實驗結果:#include<iostream> using namespace std; //父類 class Animal { protected: char animalName[30]; int height; public: Animal(char* name, int h) { strcpy_s(animalName, name); height = h; } virtual void info() { cout << "I am an animal" << endl; cout << "My name is " << animalName <<", height: "<<height << endl; } }; class Dog :public Animal { private: char voice[30]; public: Dog(char* name, int h, char* v) :Animal(name, h) { strcpy_s(voice, v); } void info() { cout << "I am a dog" << endl; cout << "My name is " << animalName << ", height: " << height << endl; } }; int main() { Animal a("cat", 20); Dog d("dog", 40, "wang"); Animal* ptr = &d; ptr->info(); Dog d1("dog1", 42, "wang wang"); Animal& p1 = d1; p1.info(); system("pause"); return 0; }
I am a dog
My name is dog, height: 40
I am a dog
My name is dog1, height: 42
- 虛函數是多态的充分條件。多态,即為多種形态,意思是:父類的指針或引用能夠操作不同的子類對象。
- 例子3:下面又定義了一個Elegent子類,在主函數中,使用父類指針指向了Elegent類的對象,可以看到,ptr1->info();這句話,由于ptr1指向的對象不同,info()執行的函數也不同,即表現為多種形态。
#include<iostream>
using namespace std;
//父類
class Animal
{
protected:
char animalName[30];
int height;
public:
Animal(char* name, int h)
{
strcpy_s(animalName, name);
height = h;
}
virtual void info()
{
cout << "I am an animal" << endl;
cout << "My name is " << animalName <<", height: "<<height << endl;
}
};
class Dog :public Animal
{
private:
char voice[30];
public:
Dog(char* name, int h, char* v) :Animal(name, h)
{
strcpy_s(voice, v);
}
void info()
{
cout << "I am a dog" << endl;
cout << "My name is " << animalName << ", height: " << height << endl;
}
};
class Elegent :public Animal
{
public:
Elegent(char* name, int h) :Animal(name, h)
{
}
void info()
{
cout << "I am an elegent" << endl;
cout << "My name is " << animalName << ", height: " << height << endl;
}
};
int main()
{
Animal a("cat", 20);
Dog d("dog", 40, "wang");
Animal* ptr = &d;
ptr->info();
Elegent e("elegent", 80);
Animal* ptr1 = &e;
ptr1->info();
system("pause");
return 0;
}
實驗結果:
I am a dog
My name is dog, height: 40
I am an elegent
My name is elegent, height: 80
3、純虛函數
- 定義:虛函數隻聲明,函數體為0,即為純虛函數。擁有純虛函數的類稱之為抽象類。
- 作用:(1)父類中定義了一個純虛函數,它的派生類(子類)必須定義,若不定義,則派生類也成為了抽象類,但是抽象類不能定義對象。(2)純虛函數為不同種類的子類對象提供了一個通用接口。
- 例子4:
#include<iostream>
using namespace std;
class A
{
private:
int a;
public:
A(int _a=0):a(_a){}
virtual void print() = 0; //純虛函數
};
class B :public A
{
private:
int b;
public:
B(int _a, int _b):A(_a),b(_b){}
void print()
{
cout << "B Class" << " " << b << endl;
}
};
int main()
{
//A a(1); //出錯,因為抽象類不能定義對象
B b(1, 2);
b.print();
system("pause");
return 0;
}
總結:
- 函數重寫、虛函數、純虛函數的聯系:父類與子類的函數原型完全相同,和函數重載有差別。
- 差別:(1)函數重寫,是子類成員函數覆寫父類的成員函數;(2)虛函數,是将父類的成員函數定義為虛函數,友善父類向子類的向下轉型;(3)純虛函數是在父類中,将虛函數的函數體置為0,為子類提供了一個接口,子類必須要實作該函數。
如果覺得對您有幫助,請幫忙點個贊吧!謝謝!