多态语法c++(自学笔记二)

函数重载和运算符重载属于静态多态,因为它们属于复用了函数名,使用的是函数重载

函数重载:

  1. 函数的返回值类型不能作为重载条件
int chongzai(){};
void chongzai(){};
#以上两者不属于重载函数
  1. 函数重载的形参数量不同
  2. 函数的函数名字相同
  3. 函数的形参类型不同
void chongzai(){};
void chongzai(int){};
#第二个函数中使用了占位参数,来达到函数重载的条件

void chongzai(float){};
void chongzai(int){};
#两个函数形参类型不同,达到函数重载的条件

继承中的函数重载

继承中用到函数重载的情况一般是在父类种,有同名的成员函数,当子类继承父类之后,想调用父类中的第二个或者第n个同名函数,需要加作用域,并且父类中的需要进行函数重载。

当子类中出现和父类同名的成员函数,子类的同名成员函数会隐藏掉父类中所有的同名成员函数,隐藏了重载的所有函数,如果想访问被隐藏的同名函数,需要在函数名前面加上父类的作用域。

#include 
using namespace std;


//继承中同名成员中的处理
class Base
{
public:
	Base()
	{
		m_a = 100;
		m_b = 200;
	}

//父类中出现了同名函数,使用占位参数作为函数重载的条件
	void func()
	{
		cout << "base作用于下的成员函数" << endl;
	}
	//同一个作用域下想要使用两个同名函数就需要进行函数重载
	void func(int)
	{
		cout << "base(int)作用于下的成员函数" << endl;
	}

	int m_a;
	int m_b;
};

class son1 :public Base
{
public:
	son1()
	{
		m_a = 200;
	}
	void func()
	{
		cout << "son作用于下的成员函数" << endl;
	}
	int m_a;
};

//当子类继承父类之后,若不加作用域,则无法访问到父类中的重载函数
void test02()
{
	son1 s1;

//访问子类
    s1.func();

//访问父类
	//加上作用域
	s1.Base::func();

	s1.Base::func(100);
}

//同名成员函数的处理方式
int main()
{

	test02();
	system("pause");
	return 0;
}

多态中的函数重写

实现多态所需要满足的条件就是:

  1. 有继承的关系
  2. 子类需要重写父类的虚函数

有继承关系就是,需要有一个子类继承父类的关系。当存在子类继承父类关系之后,就需要发生函数重写,也就是父类中的虚函数需要在子类中进行重写。

  • 虚函数

        虚函数的用法就是,在函数名或者函数的返回值类型名前加上virtual关键字

virtual void xuhanshu(){};

        当父类中定义了虚函数,子类继承父类之后,虚函数一般情况下就不会再被实现,因此也不   需要担心类内函数同名的情况。因为对于父类的虚函数,只是一种声明,实现是在子类当中。

  • 子类重写父类的虚函数

        整体来看的话,父类中的虚函数只是起到声明的作用,具体实现需要在子类中进行函数重写来完成。

        函数重写:返回指定类型 函数名 参数列表 完全相同

        

#include 
using namespace std;

//函数重载和运算符重载属于静态多态,复用函数名

//非静态成员函数不在类上储存 空类的字节是1 非静态成员变量在类上储存
class animal
{
public:
	virtual void speak()//虚函数
	{
		cout << "动物在说话" << endl;
	}

private:

};

class cat :public animal
{
public:
	//函数重写:返回指定类型 函数名 参数列表 完全相同
	void speak()
	{
		cout << "小猫说话" << endl;
	}
};

class dog :public animal
{
public:
	void speak()
	{
		cout << "小狗在说话" << endl;
	}
};

//执行说话的函数
//地制早绑定 在编译阶段就确定了函数的地址
//如果想执行让猫说话 那么这个函数的地址就不能提前绑定 需要在运行阶段进行绑定

//动态多态满足条件
//1、有继承关系
//2、子类重写父类的虚函数

//动态多态的使用
//父类的指针或引用 执行子类的对象,传入谁就调用谁的函数
//

void dospeak(animal& an)//animal& an = c
{
	an.speak();//虚函数的地址不能提前确定,看传入的是哪个对象就走哪个
}

void test01()
{
	cat c;
	//c.speak();
	dospeak(c);
	dog d;
	dospeak(d);
}

void test02()
{
	//当加上virtual之后就变成了四个字节 多了一个指针
	cout << "sizeof animal:" << sizeof(animal) << endl;
}

int main()
{
	test01();
	//test02();
	system("pause");
	return 0;
}

多态的使用

父类的指针或者引用 指向子类的对象 

当子类中重写函数完成之后,想要实现多态,就需要进行父类指针的创建,让指针指向子类的对象名,一般来说可以采用new创建堆区的方法,来创建父类的指针,这样的好处是,可以节省内存空间。
 

//这里创建了一个cpu类,属于抽象类,父类
class CPU
{
public:

    //这个函数属于纯虚函数,只是作为声明,没有实现的功能
	virtual void calculate() = 0;

};

//这里创建了一个子类intercpu

class intercpu :public CPU
{
public:
	virtual void calculate()
	{
		cout << "inter的cpu开始工作" << endl;
	}
};

//想要实现多态,就需要创建父类指针

void test01()
{
    //在堆区上开辟一块内存,让父类的指针inter指向子类,此时已经实现了多态
    CPU* inter = new intercpu;

   //接着就可以调用calculate()
    inter.calculate();
}
#输出
inter的cpu开始工作

你可能感兴趣的:(c++)