NDK13_C++基础:继承与虚函数

NDK开发汇总

一 继承

1 一个最简单的继承案例

  1. 构造函数与析构函数的调用顺序 子类对象调用父类的成员
    定义父类:
    plane.h
#pragma once
#include<string>
class Plane
{
public:
	Plane();
	Plane(std::string name,int year);
	~Plane();

	void fly();

	void land();

	void printf();

protected:
	std::string name;
	int year;
};

plane.cpp

#include <Plane.h>
#include <iostream>


using namespace std;

Plane::Plane() :name("湾流"), year(1991)
{
	cout << "Plane 无参构造函数" << this << name << year << endl;
}

Plane::Plane(std::string name, int year):name(name),year(year)
{
	cout << "Plane 构造函数" << this <<name<<year<< endl;

}

Plane::~Plane()
{
	cout << "Plane 析构函数" << this << name << year << endl;
}


void Plane::fly() {
	cout << "Plane fly"  << endl;
}

void Plane::land() {
	cout << "Plane land" << endl;
}

void Plane::printf() {
	cout << "Plane printf" << "name = "<< name<<"year = " << year << endl;
}

子类继承
Jet.h

#pragma once
#include<Plane.h>
class Jet:public Plane
{
public:
	Jet();
	Jet(std::string name, int year);
	~Jet();

private:
};

Jet.cpp

#include <Jet.h>
#include <iostream>


using namespace std;

Jet::Jet() {

	cout << "Jet  无参构造函数" << name << year << endl;
}

Jet::Jet(std::string name, int year) {

	cout << "Jet  构造函数" << name << year << endl;
}


Jet::~Jet() {
	cout << "Jet 析构函数" << endl;
}

调用:

#include <Plane.h>
#include <iostream>
#include <Jet.h>



using namespace std;

void func() {
	Jet jet;	
	jet.fly();
}

void main() {
	func();
	system("pause");
}

打印结果:

Plane 无参构造函数010FFB40湾流1991
Jet  无参构造函数湾流1991
Plane fly
Jet 析构函数
Plane 析构函数010FFB40湾流1991

如果Jet中重写fly方法,则调用Jet的fly方法;子类没有,就使用父类的,子类有实现,就用子类。

如果想子类调用父类的方法:
jet.Plane::fly();

重载(overload): 在相同作用域内,函数名称相同,参数或常量性(const)不同的相关函数称为重载。重载函数之间的区分主要在参数和常量性(const)的不同上,若仅仅是返回值或修饰符 virtual,public/protected/private的不同不被视为重载函数(无法通过编译)。不同参数是指参数的个数或类型不同,而类型不同是指各类型之间不能进行隐身类型转换或不多于一次的用户自定义类型转换(关于类型转换,请参考前文:类型转型(Type Casting))。当调用发生时,编译器在进行重载决议时根据调用所提供的参数来选择最佳匹配的函数。

重写(override):派生类重写基类中同名同参数同返回值的函数(通常是虚函数,这是推荐的做法)。同样重写的函数可以有不同的修饰符virtual,public/protected/private。

  1. 父类型引用 赋值子类型的对象,调用的是父类型中的方法
void func() {
	Jet jet;	
	Plane *p1 = &jet;
	p1->fly();

	Plane &p2 = jet;
	p2.fly();
}

运行结果

Plane 无参构造函数00AFFB60湾流1991
Jet  无参构造函数湾流1991
Plane fly
Plane fly
Jet 析构函数
Plane 析构函数00AFFB60湾流1991
  1. 给父构造函数传参,同时给对象赋值

    **重载(overload):**在相同作用域内,函数名称相同,参数或常量性(const)不同的相关函数称为重载。重载函数之间的区分主要在参数和常量性(const)的不同上,若仅仅是返回值或修饰符 virtual,public/protected/private的不同不被视为重载函数(无法通过编译)。不同参数是指参数的个数或类型不同,而类型不同是指各类型之间不能进行隐身类型转换或不多于一次的用户自定义类型转换(关于类型转换,请参考前文:类型转型(Type Casting))。当调用发生时,编译器在进行重载决议时根据调用所提供的参数来选择最佳匹配的函数。

重写(override):派生类重写基类中同名同参数同返回值的函数(通常是虚函数,这是推荐的做法)。同样重写的函数可以有不同的修饰符virtual,public/protected/private。

2.继承的权限

基类中 继承方式 子类中
public & public继承 => public
public & protected继承 => protected
public & private继承 => private

protected & public继承 => protected
protected & protected继承 => protected
protected & private继承 => private

private & public继承 => 子类无权访问
private & protected继承 => 子类无权访问
private & private继承 => 子类无权访问

3.继承的二义性 多继承 虚继承

解决二义性 虚进程 ----> 不同路径继承来的同名成员 只有一份拷贝,解决不明确的问题

class A
{
public:
	string name;
};

class A1: public A
{	 
};

class A2 :  public A
{
};



class B : public A1, public A2
{


};

B b;
//只能显示调用
b.A1::name = “Tim”;
b.A2::name = “AV”;
b.A::name = “ricky”;
如果想直接使用b.name ,需要虚继承

class A1 :virtual public A
{
};

class A2 : virtual public A
{
};

二 虚函数

增加程序的扩展性

virtual void fly();

1 虚函数引发的内存泄漏:

则在virtualFun函数中通过父类指针操作子类对象的成员函数的时候是没有问题的,可是在销毁对象内存的时候则只是执行了父类的析构函数,子类的析构函数却没有执行,这会导致内存泄漏

void zipFun() {

	//用父类的指针来出事话一个子类的对象
	Plane *jet = new Copter();
	//调用了子类中的虚函数
	jet->land();

	//回收
	delete jet;
	jet = nullptr;   //这种情况存在内存泄漏的可能
}

调用后打印:没有走子类Copter的析构函数

Plane 无参构造函数00905A08湾流1991
Copter  无参构造函数湾流1991
Copter land
Plane 析构函数00905A08湾流1991
		

解决方法 将Plane 和Copter 的析构函数都声明为虚函数(.h声明中加上virtual关键字)

2 纯虚函数(抽象类)

//纯虚函数
virtual void test() = 0;
  • 当一个类具有一个纯虚函数,这个类就是抽象类
  • 抽象类不能实例化对象
  • 子类继承抽象类,必须要实现纯虚函数,如果没有,子类也是抽象类
  • 一个类中只有纯虚函数,那么它是一个接口
  • 抽象类的作用:为了继承约束,根本不知道未来的实现

三 多态

  • 动态多态: 程序运行过程中,觉得哪一个函数被调用
  • 静态多态: 重载(函数名称相同,参数不同,面向对象的特效,c 中不行)

发生多态的条件:

  1. 继承
  2. 父类的引用或者指针指向子类的对象
  3. 函数的重写

四 Demo

Extension.zip

发布了269 篇原创文章 · 获赞 123 · 访问量 16万+

猜你喜欢

转载自blog.csdn.net/baopengjian/article/details/105128805