C++07 多态

一个类可以派生出其他的类,被派生的类称为派生类,派生派生类的类称为基类

派生类拥有基类的所有属性和方法:

	以及派生类的3种继承方法过后里面的3中标签中的属性和方法会有什么改变
	公开继承:私有成员隐藏,其他成员不变
	受保护继承:私有成员隐藏,其他成员变成受保护
	私有继承:私有成员隐藏,其他成员变成私有成员

在这个过程中,做了2个练习题来练习了一下各种继承的各种变化中间出现一个问题:想要从公开变成私有或者受保护很简单,只需要私有或者受保护继承即可,但是反过来想要从私有/受保护变成公开的话,公开继承是做不到的

这个时候,我们采用了一个特殊的方法,直接在派生类当中的公开标签中重新写一个同名函数,在该同名函数中,去调用基类的受保护方法(私有方法无法调用,因为继承后被隐藏)

这种方法叫做:函数的重写

什么叫函数重写:派生类允许重新定义基类当中的公开/受保护方法,但是注意,仅仅是重新定义。也就是说声明部分不能更改
声明部分不能更改意味着:函数的返回值和形参列表不能改变(我们的系统当中,函数返回值类型更改的话问题不是很大)

注意函数重写和函数重载的区别:

	函数重写:函数仅仅重新定义
	函数重载:函数仅仅函数名相同,参数类型必须不同
注意:一旦函数重写过后,从基类继承过来的同名函数就会消失(所谓重写就是拿着继承过来的东西重新定义)
注意:如果需要对基类的方法进行函数重载的话,注意先对他进行函数重写,否则编译报错
#include <iostream>
using namespace std;

class Base{
	public:
		virtual void func(){
			cout << "基类方法" << endl
	}

};
class Dervied1:public Base{
public:
	void func(){
		cout << "派生类1方法" << endl;
	}
};

class Dervied2:public Base{
	public:
		void func(){
			cout << "派生类2方法" << endl;
		}

};

void f(Base* b){
	b->func();
}
int main(){
	Base b;
	Dervied1 d1;
	Dervied2 d2;

	Base* b1 = &d1; //这种写法很少见
	Base* b2 = new Dervied2;//常见写法
	
	b1->func();
	b2->func();

	f(&d2);

	return 0;
}

虚函数

一个只有方法,没有属性的类,他的大小永远是1

函数由于存在于代码段,是不会占用内存的
但是一旦为其中任何一个函数加上virtual关键字,该类就会瞬间变成8个字节大小,说明该类当中多了一个”指针“

那么,这个多出来的指针指向了哪里呢?
一旦一个类当中有任何一个方法被声明称虚方法之后,该类就需要有一张虚函数列表来保存所有的虚函数。
所以,多出来的指针其实就是指向了虚函数列表中的第一个函数的函数指针。
所以,在继承过程当中,本来是将函数继承过来的,一旦该函数是虚函数的话,就会将保存了该虚函数的虚表整体继承过来,基类和派生类共享该虚表
当派生类重写基类的虚函数的时候,基类的虚表当中的函数就会发生相应的改变,那么此时,如果基类指向了派生类的话,就会优先调用虚表当中的方法,由于虚表中的方法已经被派生类改变了,所以会调用派生类重写的方法,从而实现多态

#include <iostream>
using namespace std;

class Base{
public:
	//virtual void func(){}
	virtual void func() = 0 ; //纯虚函数,一旦拥有纯虚函数,base类就会变成纯虚类,无法产生对象
}class Dervied:public Base{
public:
	void func(){}
};

int main(){
	Base* b = new Dervied;
	return 0;
}

类型转换方式

#include <iostream>
using namespace std;
class Base{
	public:
		virtual void func(){};

};

class Dervied:public Base{
	public:
		int a;
		void func(){}

};

int main(){
	Base* b = new Dervied;
	//派生类指针指向基类的时候,最正规的类型转换方式应该是使用关键字:dynamic_cast<目标类型>(目标对象)
	Dervied* d = dynamic_cast<Dervied*>(new Base);
	//d->a = 5;
	Dervied* d2 = dynamic_cast<Dervied*>(b);
	d2->a = 5;
	return 0;
}

虚函数析构函数

#include <iostream>
using namespace std;
class Base{
	public:
		virtual void func(){};
		Base(){
			cout << "基类构造" << endl;
		}
		virtual ~Base(){
			cout << "基类析构" << endl;
		}
};

class Dervied:public Base{
	public:
		Dervied(){
			cout << "派生类构造" << endl;
		}
		~Dervied(){
			cout << "派生类析构" << endl;
		}
};

int main(){
	Base* b = new Dervied;
	delete b;
	return 0;
}

工厂模式

/*
多态的具体应用:多态的主要用途就是各种不同的设计模式,我们在有意无意间使用多态的地方,其实都是设计模式
简单工厂模式:
首先,有一个工厂类,专门生产制造工具
生产出来的制造工具可以用来制造不同的产品

再有一个操作者类,他的目的是最终拿到不同的产品
他的实现过程就是:调用工厂类当中的生产工具的方法,拿到具体的工具去产生不同的产品

那么简单工厂模式该怎么写呢:
① 先要有一个工厂类
② 工厂类里面要有一个产生各种不同工具的方法
	这里面不同的工具就是多态
	先有一个工具基类
		然后有多种不同的工具继承自该基类
	工厂在调用生产工具的方法的时候,只需要该方法的返回值
	该方法的返回值必定是一个工具基类指针
③ 操作者类当中存放一个工厂类对象即可进行操作

*/

/*
	使用简单工厂模式实现一个简单的+ - * /的计算器
	工具类是谁?
		加减乘除4则运算为4个工具,因为这4个工具要制造加减程序4个运算的结果
	所以工厂类就是计算器:计算器生成工具的方法:就是根据不同的运算符返回不同的工具的过程
*/
#include <iostream>

using namespace std;

class Operator{
	int x;
	int y;
public:
	void setX(int x){this->x = x;}
	void setY(int y){this->y = y;}

	int getX(){return x;}
	int getY(){return y;}
	
	virtual double calculate() = 0;
	virtual ~Operator(){}
};

class OperatorAdd:public Operator{
public:
	double calculate(){
		return getX() + getY();
	}
};

class OperatorSub:public Operator{
public:
	double calculate(){
		return getX() - getY();
	}
};

class OperatorMul:public Operator{
public:
	double calculate(){
		return getX() * getY() * 1.0;
	}
};

class OperatorDiv:public Operator{
public:
	double calculate(){
		return getX() / (getY() * 1.0);
	}
};

class Calculator{
public:
	Operator* getOperator(char ch);
};

Operator* Calculator::getOperator(char ch){
	switch(ch){
		case '+':
			return new OperatorAdd;
		case '-':
			return new OperatorSub;
		case '*':
			return new OperatorMul;
		case '/':
			return new OperatorDiv;
		default:
			return NULL;
	}
}

int main(){
	int a = 0,b = 0;
	char ch = 0;
	double res = 0;
	Calculator cal;
	while(1){
		cout << "请输入运算表达式:";
		cin >> a >> ch >> b;
		Operator* oper = cal.getOperator(ch);
		oper->setX(a);
		oper->setY(b);
		res = oper->calculate();
		cout << "运算结果为:" << res << endl;
		delete oper;
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ava实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),可运行高分资源 Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现
C语言是一种广泛使用的编程语言,它具有高效、灵活、可移植性强等特点,被广泛应用于操作系统、嵌入式系统、数据库、编译器等领域的开发。C语言的基本语法包括变量、数据类型、运算符、控制结构(如if语句、循环语句等)、函数、指针等。下面详细介绍C语言的基本概念和语法。 1. 变量和数据类型 在C语言中,变量用于存储数据,数据类型用于定义变量的类型和范围。C语言支持多种数据类型,包括基本数据类型(如int、float、char等)和复合数据类型(如结构体、联合等)。 2. 运算符 C语言中常用的运算符包括算术运算符(如+、、、/等)、关系运算符(如==、!=、、=、<、<=等)、逻辑运算符(如&&、||、!等)。此外,还有位运算符(如&、|、^等)和指针运算符(如、等)。 3. 控制结构 C语言中常用的控制结构包括if语句、循环语句(如for、while等)和switch语句。通过这些控制结构,可以实现程序的分支、循环和多路选择等功能。 4. 函数 函数是C语言中用于封装代码的单元,可以实现代码的复用和模块化。C语言中定义函数使用关键字“void”或返回值类型(如int、float等),并通过“{”和“}”括起来的代码块来实现函数的功能。 5. 指针 指针是C语言中用于存储变量地址的变量。通过指针,可以实现对内存的间接访问和修改。C语言中定义指针使用星号()符号,指向数组、字符串和结构体等数据结构时,还需要注意数组名和字符串常量的特殊性质。 6. 数组和字符串 数组是C语言中用于存储同类型数据的结构,可以通过索引访问和修改数组中的元素。字符串是C语言中用于存储文本数据的特殊类型,通常以字符串常量的形式出现,用双引号("...")括起来,末尾自动添加'\0'字符。 7. 结构体和联合 结构体和联合是C语言中用于存储不同类型数据的复合数据类型。结构体由多个成员组成,每个成员可以是不同的数据类型;联合由多个变量组成,它们共用同一块内存空间。通过结构体和联合,可以实现数据的封装和抽象。 8. 文件操作 C语言中通过文件操作函数(如fopen、fclose、fread、fwrite等)实现对文件的读写操作。文件操作函数通常返回文件指针,用于表示打开的文件。通过文件指针,可以进行文件的定位、读写等操作。 总之,C语言是一种功能强大、灵活高效的编程语言,广泛应用于各种领域。掌握C语言的基本语法和数据结构,可以为编程学习和实践打下坚实的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值