C++笔记5(多态)


前言

本文主要介绍一下C++语言中多态的相关知识。多态是建立在继承之上的,本人认为继承使编写代码有了结构,多态则使这个结构变得可拓展,更加绚丽多彩。

多态

定义什么的我就不放了,直接说自己的见解。
多个拥有部分共同性质的对象可以继承同一个父类,在减少了代码编写量的同时保证了逻辑体系的完整,实现了“一个接口,多种方法。”

多态通过new关键子实现,在使用new的时候相当于重新申请了一个空间,当使用空间结束后要用delete四、释放空间。此时我们需要针对new和malloc进行一下区分:

  1. new/delete是C++运算符,需要编译器支持。malloc/free是库函数,需要头文件支持。

  2. 使用new操作符申请内存分配时无须指定内存块的大小,编译器会根据类型信息自行计算。而malloc则需要显式地指出所需内存的尺寸。

  3. new操作符内存分配成功时,返回的是对象类型的指针,类型严格与对象匹配,无须进行类型转换,故new是符合类型安全性的操作符。而malloc内存分配成功则是返回void * ,需要通过强制类型转换将void*指针转换成我们需要的类型。

  4. new内存分配失败时,会抛出bac_alloc异常。malloc分配内存失败时返回NULL。

  5. new会先调用operator new函数,申请足够的内存(通常底层使用malloc实现)。然后调用类型的构造函数,初始化成员变量,最后返回自定义类型指针。delete先调用析构函数,然后调用operator delete函数释放内存(通常底层使用free实现)。 malloc/free是库函数,只能动态的申请和释放内存,无法强制要求其做自定义类型对象构造和析构工作。

#include <iostream>
using namespace std;
int main(){
    int* p = (int*)malloc(sizeof(int));
    p[0] = 100;
    free(p);
    
    int* n = new int;
    *n = 200;
    delete n;
    
    int* a = new int[10];
    a[8] = 10;
    delete[] a;
    
    return 0;
}

对象是使用多态最多的。

#include <iostream>
using namespace std;

class People{
public:
    People(){
        cout << "People" << endl;
    }
    ~People(){
        cout << "~People" << endl;
    }
};
int main(){
    People* p = (People*)malloc(sizeof(People));
    free(p);
    
    People* n = new People;
    delete n;
    
    return 0;
}

函数重写/函数覆盖

  1. 父类定义虚函数;
  2. 子类实现父类的虚函数。
#include<iostream>
using namespace std;

class People {
public:
    People() {
        cout << "People" << endl;
    }
    ~People() {
        cout << "~People" << endl;
    }
    virtual void play() {   //虚函数
        cout << "吃饭 睡觉 打豆豆" << endl;
    }
};
class Student: public People {
public:
    void play() {   //函数覆盖
        cout << "王者 吃鸡 英雄联盟" << endl;
    }
};

int main() {
    Student s;
    s.play();

    return 0;
}

多态的实现

  1. 函数重写/函数覆盖
  2. 父类指针指向子类对象,并且调用子类的重写函数(运行的就是子类函数)
#include <iostream>
using namespace std;
class People {
public:
	People() {
		cout << "People" << endl;
	}
	~People() {
		cout << "~People" << endl;
	}
	virtual void play() {
		cout << "people play" << endl;
	}
};
class Student :public People {
public:
	void play() {
		cout << "student play" << endl;
	}
};
class Farmer :public People {
public:
	void play() {
		cout << "Farmer play" << endl;
	}
};
int main()
{
	Student s;
	People* p = (People*)&s;
	p->play();
	return 0;
}

在这里不得不提一下函数隐藏和函数重写的区别了。上面的代码用的就是函数重写,因为父类的的函数有virtual。如果父类没有virtual则程序输出People play,此时是函数隐藏,即子类的函数隐藏。至于为什么是子类的函数隐藏?因为p的类型是People*。

多态的应用场景

  1. 存储
int main() {
	Student s;
	Student s2;
	Student s3;
	Farmer f1;
	Farmer f2;
	Farmer f3;
	People p1;
	People p2;
	People p3;
	People* vector[10] = {&s, &s, &s3, &f1, &f2, &f3, &p1, &p2, &p3};
	return 0}

通过将多个对象存储在一个对象类型的数组里。通过这种方式也可以用循环批量调用对象的方法。

  1. 参数
    我们可以通过多态向一个函数里传递参数。
void printInfo(People* p) {
	p->play();
}

静态成员

静态成员变量

静态成员变量属于类,不属于对象。
要在类外初始化。

public:
	static int water;
};

给静态成员变量赋值:

int People::water = 100;

静态成员函数

静态成员函数不能访问非静态成员属性。

public:
	static void drink() {
		water--;
	}

缺省函数参数

缺省函数参数只能将可以缺省的参数写道右面。

#include <iostream>
using namespace std;
class People {
public:
	People(int a, int b = 0, int c =2) {
		cout << "People" << endl;
	}
};
int main()
{
	People(1);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

du__kefeng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值