一.简介
1.可维护
2.可复用
3.可扩展
4.灵活性好
面向对象的设计思想就是通过封装 继承 多态把程序的耦合性降低,使得程序更加的灵活,容易修改,并且易于复用
面向对象的五大基本原则
1.单一职责原则(SRP)
2.开放封闭原则(OCP)
3.里氏替换原则(LSP)
4.依赖倒置原则(DIP)
5.接口隔离原则(ISP)
函数编程
泛型编程
元编程
二.封装
class A{ public: A(int a){ } }
1.重载(Overload)
成员被重载的特征:(1)相同的范围,在同一个类中
(2)函数名字相同
(3)参数不同
2.抽象类和纯虚函数
纯虚函数是在基类声明的虚函数(加上 =0),它在基类中没有定义,但是要求派生类都要实现自己的实现方法
包含纯虚函数的类称为抽象类
(1) 抽象类只能用作其他类的基类,不能定义抽象类的对象
(2) 抽象类不能用于参数类型 函数返回值 或 显示转换的类型
(3) 抽象类可以定义抽象类的指针和引用,此指针可以指向它的派生类,进而实现多态性
三.继承
class B: public A{ public: B(int a,int b):A(a){ } }; class C:public A{ public: C(int a,int c):A(a){ } }; //C++允许多继承 class D:public B,public C{ public: D(int a,int b,int c):B(a,b),C(a,c),A(a){ } };
1.继承的调用顺序
#pragma once #include <iostream> using namespace std; class F{ public: F(){ k5 = 10; cout << "F:F()" << endl; } ~F(){ cout << "F:~F()" << endl; } //virtual ~F(){} void FuncA(){ cout << "F:FuncA()" << endl; } virtual void FuncB() { cout << "F::FuncB()" << endl; } int k5; protected: int k4; }; class Z : public F{ public: Z(){ k5 = 5; cout << "Z:Z()" << endl; } ~Z(){ cout << "Z:~Z()" << endl; } void FuncA(){ cout << "Z::FuncA()" << endl; } void FuncB() { cout << "Z::FuncB()" << endl; } int k5; protected: int k4; };
#include "Jicheng.h" int main() { F* a = new F(); //F() cout << endl; F* a1 = new Z(); //F() Z() cout << endl; Z* a2 = new Z(); //F() Z() cout << endl; //Z* a3 = new F(); 错误 a->FuncA(); //F:FunA() a1->FuncA(); //F:FunA() a2->FuncA(); //Z:FunA() 如果子类没有相应的函数,那么会调用父类的函数 a->FuncB(); //F:FunB() a1->FuncB(); //Z:FunB() a2->FuncB(); //Z:FunB() int k5 = a->k5; //10 int k4 = a1->k5; //10 int k3 = a2->k5; //5 //int k55 = a->k4; k4是保护成员,无法访问 delete a; //~F() cout << endl; delete a1; //如果父类析构函数加virtual 那么会多一个子类的析构函数 ~Z() ~F() cout << endl; delete a2; //~Z() ~F() cout << endl; system("pause"); return 0; }
2.继承的访问权限
(1)类继承访问权限
父类的private成员无法被继承
(1)public继承:父类的public/protected成员继承到子类的访问权限不变
(2)private继承:父类的public/protected成员继承到子类变为private
(3)protected继承:父类的public/protected成员继承到子类变为protected
(2)成员访问权限
(1)private:①能被基类函数 ②能被友元函数 访问,无法被基类对象访问
(2)protected:①能被基类函数 ②能被友元函数 ③能被子类函数 访问,无法被基类对象访问
(3)public:①能被基类函数 ②能被友元函数 ③能被子类函数 ④能被基类对象
3.继承的隐藏规则
隐藏是指派生类的函数屏蔽了与其同名的基类函数。注意只要同名函数,不管参数列表是否相同,基类函数都会被隐藏
四.多态
1.虚函数(覆盖,Override)
覆盖是指派生类函数覆盖基类函数,特征:(1)不同范围,分别位于派生类和基类
(2)函数名字相同
(3)参数相同
(4)基类函数必须有virtual关键字
主要是实现了多态的机制,简而言之就是用父类(基类)的指针指向子类(派生类)的对象,然后通过父类(基类)的指针调用不同子类(派生类)的对象的不同函数,这就是一种泛型.
一个公有派生类对象可以赋值给基类的对象,但是基类的对象不能赋值给派生类的对象
虚函数一般用于基类成员函数来绑定派生类成员函数一起调用
默认情况下成员函数不能动态绑定,但是添加virtual函数(虚函数)可以让函数有晚绑定的灵活性
2.虚函数的使用
//1.在基类用virtual声明成员函数为虚函数, class Base{ virtual void A(); }; //在类外定义虚函数无需加virtual void Base::A(){ } //2.在派生类重新定义虚函数,要求函数名/函数类型/函数参数的类型和个数保持一致 class Derive : pubic Base{ //虚函数在派生类重新声明时,无需加virtual void A(); }; //3.定义一个指向基类对象的指针变量,并使用基类对象的指针变量指向不同的派生类对象的函数 void main(){ Base* p=new Derive(); p->A(); }
class Base { public: Base() {echo();} virtual void echo() {printf(“Base”);} }; class Derived:public Base { public: Derived() {echo();} virtual void echo() {printf(“Derived”);} }; int main() { Base* base = new Derived(); base->echo(); //输出Base Derived Derived return 0; }
3.动态绑定技术
#include <iostream> using namespace std; class A { public: virtual void func(int val = 1) { std::cout " << val << std::endl; } virtual void test() { func(); } }; class B : public A { public: void func(int val = 0) { std::cout " << val << std::endl; } }; int main(int argc, char* argv[]) { A*p1 = new A; A*p2 = new B; //B*p3 = new A; //error B*p3 = reinterpret_cast<B*> (new A); B*p4 = new B; //测试test() p1->test(); //A->1 p2->test(); //B->1 p3->test(); //A->1 p4->test(); //B->1 //测试func() p1->func(); //A->1 p2->func(); //B->1 p3->func(); //A->0 p4->func(); //B->0 return 0; }
#include <iostream> using namespace std; class A { public: void func(int val = 1) { std::cout " << val << std::endl; } //这个test()的virtual可有可无 virtual void test() { func(); } }; class B : public A { public: void func(int val = 0) { std::cout " << val << std::endl; } }; int main(int argc, char* argv[]) { A*p1 = new A; A*p2 = new B; //B*p3 = new A; //error B*p3 = reinterpret_cast<B*> (new A); B*p4 = new B; //test() p1->test(); //A->1 p2->test(); //A->1 p3->test(); //A->1 p4->test(); //A->1 //func() p1->func(); //A->1 p2->func(); //A->1 p3->func(); //B->0 p4->func(); //B->0 return 0; }
4.虚析构函数
虚析构函数的作用是delete动态对象时释放资源
//test.h class A{ public: char* strA; A(char* a){ strA=new char[12]; strncpy(strA,a,strlen(a)); } virtual ~A(){ //不加virtual会报错 delete strA; } }; class B:public A{ public: char* strB; B(char* a):A(a){ strB=new char[12]; strncpy(strB,a,strlen(a)); } ~B(){ delete strB; } }; //test.cpp int main(){ char input[]="Hello"; A* a=new B(input); delete[] a; system("pause"); return 0; }