#pragma once 代表不能重复引用
多态
Plane.h
#pragma once
//普通飞机
class Plane {
public:
virtual void fly();
virtual void land();
};
Copter.h
#pragma once
#include "Plane.h"
class Copter :public Plane {
virtual void fly();
virtual void land();
};
Jet.h
#pragma once
#include "Plane.h"
class Jet :public Plane{
virtual void fly();
virtual void land();
};
Copter 和 Jet 都是Plane的子类
看看一一对应的C++文件实现
Plane.cpp
#include "Plane.h"
#include <iostream>
using namespace std;
void Plane::fly() {
cout << "起飞" << endl;
}
void Plane::land() {
cout << "着陆" << endl;
}
Copter.cpp
#include"Copter.h"
#include<iostream>
using namespace std;
void Copter::fly() {
cout <<"喷气式飞机在跑道上起飞..."<< endl;
}
void Copter::land() {
cout <<"喷气式飞机在跑道上降落"<< endl;
}
Jet.cpp
#include"Jet.h"
#include<iostream>
using namespace std;
void Jet::fly() {
cout <<"直升飞机在原地起飞"<< endl;
}
void Jet::land() {
cout <<"直升飞机降落在女神的屋顶..."<< endl;
}
//继承
//代码的重用性
例子
//人类
#include<iostream>
using namespace std;
class Hunman {
public :
void say() {
cout <<"说话"<< endl;
}
protected:
char *name;
int age;
};
class Man :public Hunman {
public:
//泡妞
void chasing() {
cout <<"泡妞"<< endl;
}
private :
//兄弟
char* brother;
};
void work(Hunman &h) {
h.say();
}
void main() {
Man m1; //子类对象
m1.say();
//1.父类类型的引用或指针
Hunman* h_p = &m1; //用父类指针指向子类地址
h_p->say();
Hunman &h1 = m1; //给子类取个别名
h1.say();
//子类对象初始化父类类型的对象
Hunman h2 = m1;
getchar();
}
//向父类构造方法传参
//人类
#include<iostream>
using namespace std;
class Human {
public:
Human(char *name,int age,bool which){
this->name= name;
this->age = age;
this->which = which;
if (which)
{
cout << "创建父类构造函数1" << endl;
}
else {
cout << "创建父类构造函数2" << endl;
}
}
void say() {
cout << "人说话" << endl;
}
protected:
char* name;
int age;
bool which;
};
//男人
class Man :public Human {
public:
//给父类构造函数传参,同时给属性对象赋值
Man(char* brother,char *s_name,int s_age,char *h_name,int h_age): Human (s_name,s_age,0),h(h_name,h_age,1) {
this->brother = brother;
cout <<"创建子类构造函数"<< endl;
}
//泡妞
void chasing() {
cout << "男人泡妞" << endl;
}
private:
//兄弟
char *brother;
Human h;
};
void main() {
Man m1("danny","jack",18,"jason",18);
m1.chasing();
m1.say();
getchar();
}
//构造函数与析构函数调用的顺序 先构造函数再析构函数#include<iostream>
using namespace std;
class Human {
public :
Human(char *name,int age) {
this->name = name;
this->age = age;
cout << "Human构造函数" << endl;
}
~Human() {
cout << "Human析构函数" << endl;
}
void say() {
cout << "说话" << endl;
}
protected:
char *name;
int age;
};
//男人
class Man : public Human {
public :
//给父类构造函数传参,同时给属性对象赋值
Man(char *brother,char *s_name,int s_age):Human(s_name,s_age){
cout << "Man的构造函数" << endl;
}
~Man() {
cout << "Man的析构函数" << endl;
}
//泡妞
void chasing() {
cout << "泡妞" << endl;
}
private:
//兄弟
char* brother;
};
void func() {
//父类构造函数先调用
//子类的析构函数先调用
Man m1("danny","jack",18);
}
void main() {
func();
getchar();
}
//子类对象调用父类的成员#include<iostream>
using namespace std;
class Human {
public:
Human(char* name,int age) {
this->name = name;
this->age = age;
cout << "Human 构造函数" << endl;
}
~Human() {
cout << "Human析构函数" << endl;
}
void say() {
cout << "说话" << endl;
}
public:
char *name;
int age;
};
//男人
class Man : public Human {
public :
Man(char* brother,char* s_name,int s_age):Human(s_name,s_age){
this->brother = brother;
cout << "Man 的构造函数" << endl;
}
~Man() {
cout << "Man 的析构函数" << endl;
}
void chasing() {
cout << "泡妞" << endl;
}
void say() {
cout << "男人就喜欢装逼" << endl;
}
private:
//兄弟
char* brother;
};
void main() {
//是覆盖,并非动态
Man m1("alan","jack",22);
m1.say();
m1.Human::say();
m1.Human::age = 10;
getchar();
}
//多继承
//人
class Person {
};
//公民
class Citizen {
};
//学生,既是人,又是公民
class Student :public Person, public Citizen {
};
//继承的访问修饰
//基类中 继承方式 子类中
//public & public继承 = > public
//public & protected继承 = > protected
//public & private继承 = > private
//
//protected & public继承 = > protected
//protected & protected继承 = > protected
//protected & private继承 = > private
//
//private & public继承 = > 子类无权访问
//private & protected继承 = > 子类无权访问
//private & private继承 = > 子类无权访问
//人类
class Human {
public :
void say() {
cout << "说话" << endl;
}
private:
char *name;
int age;
};
//男人
class Man : protected Human {
public:
//泡妞
void chasing() {
cout << "泡妞" << endl;
}
private:
//兄弟
char* brother;
};
//继承的二义性
//虚继承,不同路径继承来的同名成员只有一份拷贝,解决不明确的问题class A {
public:
char *name;
};
class A1 :virtual public A {
};
class A2 :virtual public A {
};
class B : public A1,public A2 {
};
void main() {
B b;
b.name = "jason";
//指定父类显示调用
b.A1::name = "tiya";
b.A2::name = "jack";
getchar();
}
//虚函数
//多态(程序的拓展性)
//动态多态:程序在运行过程中,觉得哪一个函数被调用
//静态多态:重载
//发生动态的条件:
//1.继承
//2.父类的引用或者指针指向子类的对象
//3.函数的重写#include"Plane.h"
#include"Jet.h"
#include"Copter.h"
//业务函数
void bizPlay(Plane &p) {
p.fly();
p.land();
}
void main() {
Plane p1;
bizPlay(p1);
//直升飞机
Jet p2;
bizPlay(p2);
Copter p3;
bizPlay(p3);
getchar();
}
//纯虚函数(抽象类)
//1.当一个类具有一个纯虚函数,这个类就是抽象类
//2.抽象类不能实例化对象
//3.子类继承抽象类,必须要实现纯虚函数,如果没有,子类也是抽象类
//抽象类的作用:为了继承约束,根本不知道未来的实现
//形状class Shape {
public:
//纯虚函数
virtual void sayArea() = 0;
void print() {
cout << "Hi" << endl;
}
};
//圆
class Circle : public Shape {
public :
Circle(int r) {
this->r = r;
}
void sayArea() {
cout <<"圆的面积:"<< (3.14 * r * r)<< endl;
}
private :
int r;
};
void main() {
//Shape a;
Circle c(10);
c.sayArea();
Circle(10).sayArea();
getchar();
}
//接口(只是逻辑上的划分,语法上跟抽象类的写法没有区别)
//可以当作一个接口class Drawable{
virtual void draw();
};
//模板函数(泛型)
普通写法
void myswap(int &a,int &b) {
int tmp = 0;
tmp = a;
a = b;
b = tmp;
}
void myswap(char &a, char &b) {
char tmp = 0;
tmp = a;
a = b;
b = tmp;
}
发现:这两个函数业务逻辑一样,数据类型不一样template <typename T>
void myswap(T &a,T &b) {
T tmp = 0;
tmp = a;
a = b;
b = tmp;
}
//根据实际类型,自动推导
void main(){
int a = 10, b = 20;
myswap<int>(a,b);
cout << a << "," << b<< endl;
char x = 'v',y='w';
myswap(x,y);
cout << x << "," << y << endl;
getchar();
}
template<class T>
class A {
public:
A(T a) {
this->a = a;
cout << a << endl;
}
protected:
T a;
};
//普通类继承模板
class B :public A<int> {
public :
B(int a ,int b):A<int>(a){
this->b = b;
}
private :
int b;
};
//模板类继承模板类
template <class T>
class C :public A<T> {
public:
C(T c,T a):A<T>(a){
this->c = c;
}
protected:
T c;
};
void main() {
//实例化模板类对象
//List<String> list;
A<int> a(6);
getchar();
}
c++异常处理,根据抛出的异常数据类型,进入到相应的catch块中
void main() {
try {
int age = 300;
if (age>200)
{
throw 9.8;
}
}
catch (int a) {
cout <<"int异常"<< endl;
}
catch (char* b) {
cout << b << endl;
}
catch(...){
cout << "未知异常" << endl;
}
getchar();
}
void mydiv(int a ,int b) {
if (b==0)
{
throw "除数为0";
}
}
void func() {
try {
mydiv(8,0);
}
catch(char* a){
throw a;
}
}
void main() {
try {
func();
}
catch (char* a) {
cout << a << endl;
}
getchar();
}
//抛出对象
//异常类
class MyException {
};
void mydiv(int a ,int b) {
if (b==0)
{
throw MyException();
}
//throw new MyException; 不要抛出异常指针
};
void main() {
try {
mydiv(8,0);
}
catch (MyException& e1) {
cout << "MyException引用" << endl;
}
//会产生对象副本
//catch (MyException e2) {
// cout << "MyException" << endl;
//}
catch (MyException* e3) {
cout << "MyException指针" << endl;
delete e3;
}
getchar();
}
void mydiv(int a ,int b)throw(char* ,int) {
if (b==0)
{
throw"除数为零";
}
}
#include<stdexcept>
class NullPointerException : public exception {
public :
NullPointerException(char* msg) :exception(msg) {
}
};
void mydiv(int a,int b) {
if (b>10)
{
throw out_of_range("超出范围");
}
else if (b==NULL)
{
throw NullPointerException("为空");
}
else if (b==0) {
throw invalid_argument("参数不合法");
}
}
void main() {
try {
mydiv(8,NULL);
}
catch (out_of_range e1) {
cout << e1.what() << endl;
}
catch (NullPointerException& e2) {
cout << e2.what() << endl;
}
catch (...) {
}
getchar();
}
外部类异常
class Err {
public :
class MyException {
public:MyException() {
cout << "MyException" << endl;
}
};
};
void mydiv(int a,int b) {
if (b>10)
{
throw Err::MyException();
}
}
void main() {
try
{
mydiv(8, 20);
}
catch (...)
{
}
getchar();
}
//向父类构造方法传参
//人类