栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

C++多态(上):

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++多态(上):

--------------"感谢在那每一次跌倒了以后,又重新来过"


(1)多态的概念以及定义: ①定义:

多态:俗称多种形态。每个具体的行为,去做同一件事情,产生不同的状态。

对语言来说,也就是灵活调用。

多态有两个种类;

1.静态的多态,也就是函数重载;(编译时,依靠函数名修饰规则)

2.动态的多态(运行时,找到父类、子类虚函数),构成条件如下......

(2)多态实现: 构成条件:

1. 必须通过基类的指针或者引用调用虚函数

2. 被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写

父类指针、引用指向父类对象 调用父类虚函数

父类指针、引用指向子类对象 调用子类虚函数         ----->指向哪个对象的调用哪个

这里就有个问题---->什么是虚函数?


(3)虚函数:

即被virtual修饰的函数(这和虚继承的关键字一样,但意义不一样!!!)

class Person
{
public:
    //虚函数
	virtual void PrintTicket()
	{
		cout << "买票---全价" << endl;
	}
};
什么又叫做虚函数重写呢?
class Person
{
public:
	virtual void PrintTicket()
	{
		cout << "买票---全价" << endl;
	}
};

class Student:public Person
{
public:
	virtual void PrintTicket()
	{
		cout << "买票---半价" << endl;

	}
};

class Soilder:public Person
{
public:
	virtual void PrintTicket()
	{
		cout << "买票---优先" << endl;
	}
};

也就是,在派生类中有一个跟基类完全相同的虚函数。

他们在返回类型、函数名、参数列表 完全相同。

class Person
{
public:
	virtual void PrintTicket()
	{
		cout << "买票---全价" << endl;
	}
};

//虚函数重写
class Student :public Person
{
public:
	virtual void PrintTicket()
	{
		cout << "买票---半价" << endl;

	}
};

class Soilder :public Person
{
public:
	virtual void PrintTicket()
	{
		cout << "买票---优先" << endl;
	}
};

//父类指针引用     调用
void Func(Person& p)
{
	p.PrintTicket();
}

void Func(Person* p)
{
	p->PrintTicket();
}


虚函数重写例外(例外 构成重写条件) 1.协变(基类和派生类 返回值可以不同)

我们来看看下面代码:

class A{};

class B :public A{};

class ForA 
{
public:
	virtual A* Print()
	{
		cout << "ForA()" << endl;
		return new A;
	}
};

class ForB:public ForA
{
public:
	virtual B* Print()
	{
		cout << "ForB()" << endl;
		return new B;
	}
};

A是基类,B是子类。他们分别作为另外一组继承关系的返回值。 此时他们构成协变。

2.析构函数的重写:
class A 
{
public:
	~A()
	{
		cout << "~A()" << endl;
	}
};

class B:public A
{
public:
	~B()
	{
		cout << "~B()" << endl;
	}
};

我们分别对A、B生成的对象进行析构 

 这和我们想要的不太一样。因为我们new 出来的B类并没有去调用析构 反而调用了两次A析构。

我们知道,编译器会把基类、派生类的析构函数统一改成,destructor(),从而隐藏,但在这里也就误打误撞构成 也就完成了重写。

class A 
{
public:
     //基类 带上虚函数 方便 子类重写
	  virtual ~A()
	{
		cout << "~A()" << endl;
	}
};

class B:public A
{
public:
	virtual ~B()
	{
		cout << "~B()" << endl;
	}
};

从而,让虚函数进行重写了。a,b才能分别找到自己对应的 析构函数进行 清理!实现多态。  

3.基类构成虚函数后,子类只需要重写

这个也算C++设计的一个坑。搞得重写不太严谨。

这样的理由在于,析构时,让父类构成虚函数(virtual)后,子类也就继承virtual的属性,让子类也对函数进行了重写。

class A 
{
public:
    //这只让 A 构成虚函数
	  virtual ~A()
	{
		cout << "~A()" << endl;
	}
};

class B:public A
{
public:
   //继承 虚函数的特性
	 ~B()
	{
		cout << "~B()" << endl;
	}
};


 (4)C++11引入新关键字

final:修饰的虚函数不能被继承

class Car
{
public:
	virtual void Drive() final{}
};

class BMW :public Car
{
public:
	virtual void Drive();
};

2.override:检查派生类虚函数是否重写了基类某个虚函数,如果没有重写编译报错

class Car
{
public:
	virtual void Drive() {}
};

class BMW :public Car
{
public:
	virtual void Drive() override
	{}
};

(5)概念对比与区别

学到现在,一定对有些概念记得混淆。重写、隐藏、重定义.......

 


 多态上篇也就告一段落,感谢你的阅读。

祝你好运~

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1019840.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号