虚函数和多态、纯虚函数和抽象类、友元函数和友元类、模板函数和模板类(C++四)

目录

  • 一、虚函数和多态
    • 1. 引入多态和虚函数
    • 2.多态实现的前提条件
    • 3. 原理
    • 4.C++中多态可以划分为两大类
  • 二、类的包含 ->类的嵌套
  • 三、纯虚函数和抽象类
    • 1. 纯虚函数:
      • (1)跟虚函数的关系
      • (2)语法
      • (3)作用
    • 2. 抽象类
      • (1)定义
      • (2)作用
      • (3)特点
      • (4)常见的错误
  • 四、虚析构函数
    • 1. 析构函数只有一种写法
    • 2.作用
  • 五、友元函数和友元类
    • 1. 引入友元
    • 2.特点
    • 3. 友元的几种情况
    • 4. 友元的优点缺点
      • (1)优点
      • (2)缺点
  • 六、模板函数和模板类(泛型编程)
    • 1. 引入模板
    • 2. 模板函数
      • (1)定义
      • (2)语法
      • (3)特点
    • 3. 模板类
      • (1)定义
      • (2)语法

一、虚函数和多态

1. 引入多态和虚函数

多态: 通俗理解就是多种表现形式 -> 同一个接口有多种表现形式

父类的指针或者父类的引用指向子类对象,你传递参数的时候传递的是子类A就调用A的方法,传递的是子类B就调用B的方法 -> C++把这种技术称作多态

虚函数: 在某基类中声明为 virtual 并在一个或多个派生类中被重新定义的成员函数,实现多态性,通过指向派生类的基类指针或引用,访问派生类中同名覆盖成员函数。

用法格式为

virtual 函数返回类型 函数名(参数表)
{
	函数体
}

2.多态实现的前提条件

①必须要有继承,有了继承C++语法才允许你父类的指针或者父类的引用指向子类对象

②父类的同名函数必须定义成虚函数

③子类必须重写父类的同名方法

3. 原理

①只要一个类中定义了虚函数,那么这个类以及它派生出来的类都会有各自独立的虚函数表,并且创建的对象中会多出来一个指针(该指针指向虚函数表的首地址)

②父类的指针或者父类的引用去调用方法的时候,其实就是去查询虚函数表

4.C++中多态可以划分为两大类

第一类:编译时多态 -> 函数重载就是编译时多态

第二类:运行时多态 -> 我们现在用虚函数实现的这种就是运行时多态

二、类的包含 ->类的嵌套

类的嵌套:一个类的对象作为另外一个类的成员

class Book
{
public:	
	Book()
	{
		
	}
	Book(string newname)
	{
		bookname=newname;
	}
private:
	string bookname;
};

//定义读者类
class Reader
{
public:
	void getBook(Book &newbook)
	{
		somebook=newbook;
	}
private:
	Book somebook;  //调用无参构造函数
};

三、纯虚函数和抽象类

1. 纯虚函数:

(1)跟虚函数的关系

纯虚函数是虚函数的一种特殊情况

(2)语法

virtual  函数返回值  函数名字()=0;//纯虚函数没有任何具体代码,只有一个声明

(3)作用

提供一个统一接口,实现要求程序员根据自己的情况各自去实现(要前向引用声明)

2. 抽象类

(1)定义

只要一个类中声明了纯虚函数,那么这个类就是抽象类

(2)作用

跟纯虚函数配合,提供接口声明给程序员,提供给程序员提供的共同的操作接口,程序员依照统一的接口去实现各自的功能

(3)特点

①抽象类是不能定义对象的

②一个类继承了抽象类,必须实现抽象类中所有的纯虚函数,如果有一个不实现,那么子类依然是抽象类

③抽象类也可以定义构造函数,作用用于子类新建对象的时候会调用父类(抽象类)的构造方法

(4)常见的错误

①子类没有将父类(抽象类)中的纯虚函数都实现

②子类“实现了父类(抽象类)中所有的纯虚函数”,函数类型不一样

例:

class 父类
{
		public:
				virtual void show()=0;
}
class 子类:public 父类
{
		public:
				void show(string name)
				{
						cout<

四、虚析构函数

1. 析构函数只有一种写法

virtual  ~类的名字()
{
	函数体;
}

2.作用

父类的指针指向子类对象的时候,delete释放父类指针,默认只会调用父类的析构,不会调用子类的析构(万一子类中有堆空间没有释放怎么办呢??)

解决方法: 在父类的析构函数前面加上virtual关键字即可

注意:只要代码中涉及到继承,你都把父类的析构函数定义成虚析构

五、友元函数和友元类

1. 引入友元

C++提供了不需要使用继承,直接就能访问其他类的所有成员的一种机制

2.特点

①友元是单向

比如:A是B的友元,但是你不能B也是A的友元

②友元是不能传递,也不能继承的

比如:A是B的友元,A是C的友元,不能认为B和C也是友元关系

A是B的友元,不能认为A的子类也是B的友元

3. 友元的几种情况

①普通函数作为一个类的友元

friend void getCardMsg(Card &card);

② 一个类的成员函数作为另外一个类的友元(注意写法,很容易写错)

friend void People::getCardMoney(Card &card);

③友元类,一个类整体作为另外一个类的友元

firiend class Card;

4. 友元的优点缺点

(1)优点

①提供了一种可以直接访问类的私有,保护,公有成员的一种方法(不需要通过继承,不需要通过修改权限,只需要声明成友元)

②提高了程序的运行效率(减少了系统用于安全性检查的时间消耗,编译器不用再去检查你定义的权限)

(2)缺点

破坏了类的封装性

六、模板函数和模板类(泛型编程)

泛型:通用的类型

1. 引入模板

C++把函数参数的类型抽象出来 -> 定义成模板

2. 模板函数

(1)定义

只要一个函数中使用了模板,这个函数就叫做模板函数

例:

int add(int a,int b)
double add(double a,double b)//函数重载

T  add(T a,T b)//模板

(2)语法

template <class 模板的名字,class 模板的名字>//声明一个模板

template <typename 模板的名字,typename 模板的名字>  //typename和class都是一样的作用
函数的定义
{
		函数体;
}

(3)特点

①每个模板函数必须单独声明模板,不能共用同一个模板

②模板函数跟具体版本的函数混合在一起,优先使用具体版本的函数

编译器会通过你传递的实参的类型去实例化模板函数(翻译你的模板函数为具体类型的函数)

3. 模板类

(1)定义

只要一个类中使用了模板,这个类称作模板类

template //模板类
class  Pic
{  };

Pic a;//定义对象

(2)语法

template <class 模板的名字,class 模板的名字>//声明一个模板
class 类名
{
	模板的名字 属性名;
}

类名<类型>对象;//使用

你可能感兴趣的:(编程语言,c++,开发语言,visual,studio)