c++ day13(1) 多态,计算器类案例(new 创建对象)

1.基本概念

多态分为两类

  • 静态多态:函数重载和运算符重载属于静态多态,复用函数
  • 动态多态:派生类和虚函数实现运行时多态

静态多态和动态多态区别

  • 静态多态的函数地址早已绑定——编译阶段确定函数地址
  • 动态多态的函数地址晚绑定——运行阶段确定函数地址

动态多态条件

  1. 继承关系
  2. 子类和父类有函数重写(即函数同名)

动态多态使用

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

void dospeak(school &s)  //父类的指针或引用指向子类的对象
{
    s.index();

}

class school
{
public:
	//虚函数(父类必加,子类无所谓)
	virtual void index()
	{
		cout << "通知" << endl;
	 }
};

class teacher :public school
{
public:
	void index()
	{
		cout << "老师转发通知" << endl;
	}
};

class student :public school
{
public:
	void index()
	{
		cout << "学生转发通知" << endl;
	}
};

void dospeak(school &s)  //父类的指针或引用执行子类的对象
{
	s.index();//因为此时用的是school类的对象,所以地址早绑定。与传入的对象是哪个子类无关,运行的是父类中的index()函数
}


//如果想传输的哪个子类就运行哪个子类的index函数,必须让函数地址晚绑定,在运行阶段进行
//在父类函数前加virtual
void test()
{
	teacher t;
	dospeak(t);
	student s;
	dospeak(s);//根据传输对象再确定地址
}

int main()
{
	test();
	system("pause");
	return 0;
}

 

2.多态的深入剖析 (不好写,看视频136课)

3.计算器类案例

实现两个操作数相加

普通写法

class school
{
public:
	int m_age;
	int m_num;
	int sum(string oper)    //传入符号做判断
	{
		if (oper == "+")
		{
			return m_age + m_num;
		}
		else if (oper == "-")
		{
			return m_age - m_num;
		}	
	}
};


void test()
{
	school s; string oper;
	
	s.m_age = 19; s.m_num = 23;
	cout << "请输入加或减符号" << endl;
	cin >> oper;
	cout << s.sum(oper) << endl;
}

int main()
{
	test();
	system("pause");
	return 0;
}

自己写的。

存在问题:如果用一个新的类添加新的计算功能,在使用虚函数的情况下,必须有新的类建立一个对象,才能使用新功能,且旧的功能也必须用函数所在的类创建一个对象

class calculator
{
public:
	int m_age;
	int m_num;
	virtual int sum(string oper)    //传入符号做判断
	{
		if (oper == "+")
		{
			return m_age + m_num;
		}
		else if (oper == "-")
		{
			return m_age - m_num;
		}		
	}
};

class cal2 :public calculator
{
public:
	 int sum(string oper)
	{
		if (oper == "*")
		{
			return m_age * m_num;
		}
	}
};

void add(calculator &c,string &oper )
{
	c.sum(oper);
}

void test()
{
	cal2 c; string oper;
	calculator s;
	s.m_age = 119; s.m_num = 233;
	c.m_age = 19; c.m_num = 23;
	cout << "请输入符号" << endl;
	cin >> oper;
	add(c, oper); add(s, oper);
	//cout << c.sum(oper) << endl;
	cout << s.sum(oper) << endl; //父类的函数变成虚函数后   
	//父类,子类建立的对象好像只能也各自调用各自类的函数,不能直接子类调用所有函数。
	
}

老师答案.

组织性强,拓展性高

虽然各自类也只能调用各自类的函数,但实现起来简单

重点:calculator *c = new add(); //这里父类创建了一个指针,接收了new为add类开辟的一块内存的地址,这块内存相当于add类实例化的一个对象
    //因此满足了多态,父类的指针或引用指向子类的对象这个条件

又因为父类的函数是虚函数,则各个计算函数的调用,c->getresult()由实例化的类的类型决定。

子类的virtual不是必须,可写可不写

class calculator
{
public:
	int m_num1;
	int m_num2;
	virtual int getresult()
	{
		return 0;
	}
};

//加法计算器类
class add :public calculator
{
public:
	virtual int getresult()
	{
		return m_num1 + m_num2;
	}
};

class sub :public calculator
{
public:
	virtual int getresult()
	{
		return m_num1 - m_num2;
	}
};
	

class mul :public calculator
{
public:
	virtual int getresult()
	{
		return m_num1 * m_num2;
	}
};

void test()
{
	calculator *c = new add(); //这里父类创建了一个指针,接收了new为add类开辟的一块内存的地址,这块内存相当于add类实例化的一个对象
	//因此满足了多态父类的指针或引用指向子类的对象这个条件
	c->m_num1 = 10; c->m_num2 = 20;
	cout << c->getresult() << endl;  //也是只能用一次
	delete c; //记得销毁
	c = new sub();   //这里只是销毁了内存数据,c还是个指针。new 类型后记得加()
	c->m_num1 = 10; c->m_num2 = 20;
	cout << c->getresult() << endl;  //也是只能用一次
	delete c;
}

int main()
{
	test();
	system("pause");
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值