C++——封装、继承、多态

三大特征

  • 封装
  • 继承
  • 多态

三大特征包括:封装、继承、多态。
封装可以隐藏实现细节,使得代码模块化;
继承可以扩展已存在的模块,它们目的都是为了代码重用;
多态则是为了实现: 接口重用。

封装

  1. 概念:
    ①:该隐藏的数据私有化,该公开的公有化(接口)(private、public);
    ②:目的就是为了分工合作,有助于使用的方便和安全性;
    ③:防止不必要的扩展。

继承

  1. 概念:
    实现代码和数据的复用,复用的实现在已有的代码和数据的基础上扩展。
    例如:AX继承了A这个类showx的功能,又拓展了showy的特征。
#include 

using namespace std;

class A{
	public:
		A(){}
		~A(){}
		void showx(){
			cout << "xxxxxxxxxxxxxxxxxxxx" << endl;
		}

};

class AX:public A{
	public:
		void showy(){
			cout << "yyyyyyyyyyyyyyyyyyyy" << endl;
		}
};

int main()
{
	A a;
	a.showx();

	AX b;
	b.showx();
	b.showy();
}

  1. 继承的方式及语法:
    ①公有继承 ----------- class B:public A{…};
    父类的公有数据在子类中仍然公开
    父类的受保护数据在子类中仍然受保护
    父类的私有数据在子类中是隐藏的
    ②保护继承 ----------- class B:protected A{…};
    父类的公有数据在子类中变为受保护
    父类的受保护数据在子类中仍然受保护
    父类的私有数据在子类中是隐藏的
    ③私有继承 ----------- class B:private A{…};
    父类的公有数据在子类中变为私有
    父类的受保护数据在子类中变为私有
    父类的私有数据在子类中是隐藏的

  2. 注意:
    ①:父类中的成员在子类中的访问权限只会收缩,不会扩大,在子类中的访问属性不会超过继承方式。
    ②:所谓的继承方式就是能够提供给子类的最大访问权限,实际权限小于等于继承方式,私有的数据必然在子类中隐藏

多态

  1. 概念:在 C++中,用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数,大大提高编程的效率和灵活性,即C++多态性。
#include 
using namespace std;

class A{
	public:
		A(){}
		~A(){}
		virtual void show(){
			cout << "AAAAAAAAAAAAAAAAAAAAA" << endl;
		}

};

class AX:public A{
	public:
		void show(){
			cout << "BBBBBBBBBBBBBBBBBBBBB" << endl;
		}
};

int main()
{
/*
	A a;
	a.show();
	AX b;
	b.show();
*/
	AX a;
	AX *q = &a;
	A  *p = &a;

	q->show();
	p->show();
}

编译时的多态性是通过重载实现的,而运行时的多态性则是通过虚函数实现的。

虚函数:就是在类普通成员函数前加virtual修饰。一旦一个类中有虚函数(Virtual Function),编译器将为类生成虚函数列表(Virtual Table)。
如果父类中有虚函数,子类中重写了该虚函数,使用父类类型记录子类对象时,调用这个函数就回去调用子类中被重写的函数,而不会调原虚函数。普通的成员函数没有这个特性。

  1. 应用:求多个三角形,圆形,正方形的周长。
#include 
using namespace std;

class shape{
public:
	virtual double getC(void) = 0; //纯虚函数
//	{
	
//	}

};

class Cir:public shape{
public:
	Cir(double ri):r(ri){   }
	double getC(void){
		return 2*3.14*r;
	}
private:
	int r;
};

class Tri:public shape{
public:
	Tri(double a,double b,double c):e1(a),e2(b),e3(c) {  }
	double getC(void){
		return e1+e2+e3;
	}
private:
	double e1;
	double e2;
	double e3;
};

class Rec:public shape{
public:
	Rec(double a):e1(a) {  }
	double getC(void){
		return 4*e1;
	}
private:
	double e1;
};

double contC(shape *arr[],int n)
{
	double sum = 0;
	for(int i=0;i<n;i++)
	{
		sum += arr[i]->getC();
	}
	return sum;
}
int main()
{
//	shape x;    验证纯虚函数

	Cir a(1);
	Rec b(2);
	Cir c(3);
	Tri d(4,4,4);

	shape *arr[] = {&a,&b,&c,&d};
	
	cout << "total C:" << contC(arr,4) << endl;
}

多态总结:
①:多态的基础是继承
②:虚函数是实现多态的关键
③: 虚函数重写(函数覆盖)是多态的必要条件

补充:
虚析构函数:
析构函数是为了在对象不被使用之后释放它的资源,虚函数是为了实现多态。
那么把析构函数声明为vitual有什么作用呢?
直接的讲,C++中基类采用virtual虚析构函数是为了防止内存泄漏。
具体地说,如果派生类中申请了内存空间,并在其析构函数中对这些内存空间进行释放。假设基类中采用的是非虚析构函数,当删除基类指针指向的派生类对象时就不会触发动态绑定,因而只会调用基类的析构函数,而不会调用派生类的析构函数。那么在这种情况下,派生类中申请的空间就得不到释放从而产生内存泄漏。所以,为了防止这种情况的发生,C++中基类的析构函数应采用virtual虚析构函数。

#include 
using namespace std;

class A{
	public:
		A(){}
		virtual ~A(){cout << "A~~~~~~~~~~~~~~~~~~" << endl;}
		void show(){
			cout << "AAAAAAAAAAAAAAAAAAAAA" << endl;
		}

};

class AX:public A{
	public:
		~AX() {cout << "AX~~~~~~~~~~~~~~~~~" << endl;}
		void show(){
			cout << "BBBBBBBBBBBBBBBBBBBBB" << endl;
		}
};

int main()
{
//	AX a;

//	AX *p = new AX;
//	delete p;

	A *p = new AX;
	delete p;

}

你可能感兴趣的:(C++/QT,c++,开发语言,后端)