天天看點

C++類中的函數重寫(覆寫)、虛函數、純虛函數的差別與聯系1、函數重寫(覆寫)2、虛函數3、純虛函數

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. 差別:(1)函數重寫,是子類成員函數覆寫父類的成員函數;(2)虛函數,是将父類的成員函數定義為虛函數,友善父類向子類的向下轉型;(3)純虛函數是在父類中,将虛函數的函數體置為0,為子類提供了一個接口,子類必須要實作該函數。

如果覺得對您有幫助,請幫忙點個贊吧!謝謝!

繼續閱讀