继承和多态

继承

继承的构造和析构的循序:先父类再子类,然后子类析构父类析构

访问同名的成员变量需要加作用域其为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include

using namespace std;

class Base{
public:
int a;
Base(){
a=100;
}
void fun(){
cout<<"父类同名函数"<<endl;
}
void fun(int a){
cout<<"父类同名函数"<<endl;
}
protected:
int b;
private:
int c;
};
class A:public Base{
public:
A(){
a=23;
}
int a;
void fun(){
cout<<"子类同名函数"<<endl;
}
};
class B:protected Base{
};
class C:private Base{
};
void test(){
A a1;
cout<endl;
cout<endl;
a1.fun();
a1.Base::fun();
//若想访问到父类的同名成员函数加作用域
a1.Base::fun(1000);
//访问静态成员
//子类::父类::静态变量;表示通过类名访问父类作用域下的静态变量
}
int main(){
test();
}

多继承

子类:继承方式 父类,继承方式 父类…

菱形继承问题

image-20191117222518708

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include

using namespace std;

class Base{
public:
int age;
};
class A:virtual public Base{
};
class B:virtual public Base{
};
class C:public A,public B{
};
void test(){
C c;
c.age=100;
c.age=23;
cout<endl;
}
int main(){
test();
}

多态

多态的条件: 1 继承 2 子类覆写父类的方法

使用 父类的引用指向子类的对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include

using namespace std;

class Annimal{
public:
virtual void speak(){ //虚函数实现多态
cout<<"动物在说话"<<endl;
}
};
class Cat:public Annimal{
void speak(){
cout<<"小猫在说话"<<endl;
}
};
class Dog:public Annimal{
void speak(){
cout<<"小狗在说话"<<endl;
}
};

void doSpeak(Annimal &annimal){
annimal.speak();
}
void test(){
Cat cat;
doSpeak(cat);

}
int main(){
test();
}

纯虚函数和抽象类

1
2
virtual void speak()=0;有了纯虚函数我们城为抽象类,无法实例化对象
子类必须重写父类的方法;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include

using namespace std;

class AbstractDrinking{
public:
//煮水
virtual void Boil()=0;
//冲泡
virtual void Brew()=0;
//倒入杯中
virtual void PourInCup()=0;
//加料
virtual void PutSomething()=0;
void makeDrink(){
Boil();
Brew();
PourInCup();
PutSomething();
}
};
class Coffee:public AbstractDrinking{
public:
//煮水
virtual void Boil(){
cout<<"煮水"<<endl;
}
//冲泡
virtual void Brew(){
cout<<"冲泡"<<endl;
}
//倒入杯中
virtual void PourInCup(){
cout<<"导入杯中"<<endl;
}
//加料
virtual void PutSomething(){
cout<<"加料"<<endl;
}
};
class Tea:public AbstractDrinking{
public:
//煮水
virtual void Boil(){
cout<<"煮水"<<endl;
}
//冲泡
virtual void Brew(){
cout<<"冲泡茶叶"<<endl;
}
//倒入杯中
virtual void PourInCup(){
cout<<"导入杯中"<<endl;
}
//加料
virtual void PutSomething(){
cout<<"加料"<<endl;
}
};


void doWork(AbstractDrinking *abs){
abs->makeDrink();
delete abs;
}
void test(){
doWork(new Coffee);
doWork(new Tea);

}
int main(){
test();
}

纯虚析构需要声明也需要实现

image-20191121160323393

image-20191121160358800

image-20191121160431500

image-20191121160500114

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include


using namespace std;

class Cpu{
public:
virtual void caculate()=0;
};
class VideoCard{
public:
virtual void display()=0;
};
class Memory{
public:
virtual void storage()=0;
};

class Computer{
public:
Computer(Cpu *cpu,VideoCard *videoCard,Memory *memory){
this->cpu=cpu;
this->videoCard=videoCard;
this->memory=memory;
}
void Work(){
cpu->caculate();
videoCard->display();
memory->storage();
}
~Computer(){
if(cpu!=NULL){
delete cpu;
}
if(videoCard!=NULL){
delete videoCard;
}
if(memory!=NULL){
delete memory;
}
}
private:
Cpu *cpu;
VideoCard *videoCard;
Memory *memory;

};
class IntelCpu:public Cpu{
public:
virtual void caculate(){
cout<<"Intel的cpu"<<endl;
}
};
class IntelVideoCard:public VideoCard{
public:
virtual void display(){
cout<<"Intel的显示器"<<endl;
}
};
class IntelMemory:public Memory{
public:
virtual void storage(){
cout<<"Intel的内存"<<endl;
}
};
class LenovoCpu:public Cpu{
public:
virtual void caculate(){
cout<<"Lenovo的cpu"<<endl;
}
};
class LenovoVideoCard:public VideoCard{
public:
virtual void display(){
cout<<"Lenovo的显示器"<<endl;
}
};
class LenovoMemory:public Memory{
public:
virtual void storage(){
cout<<"Lenovo的内存"<<endl;
}
};
void test(){
Computer *com=new Computer(new IntelCpu,new LenovoVideoCard,new IntelMemory);
com->Work();
delete com;
}
int main(){
test();
}

文件操作

image-20191121164144152

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include
#include

using namespace std;

void write(){
ofstream ofs;
ofs.open("test.txt",ios::app);
ofs<<"张三"<<endl;
ofs<<"李四"<<endl;
ofs.close();
}
void read(){
ifstream ifs;
ifs.open("test.txt",ios::in);
if(!ifs.is_open()){
cout<<"文件打开失败"<<endl;
}
//四种方式读取
//1
char buf[1024]={0};
while(ifs>>buf){
cout<endl;
}
//2
char buf2[1024]={0};
while(ifs.getline(buf2,sizeof(buf2))){
cout<endl;
}
//3
string buffer;
while(getline(ifs,buffer)){
cout<<buffer;
}
//4单个读取
char c;
while(c=ifs.get()!=EOF){
cout<endl;
}
ifs.close();
}
int main(){
write();
read();
}

模板必须推导出数据类型才可以使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include

using namespace std;


template<class T>
void add(T a,T b){
cout<endl;
}

void test(){
add<int>(23,12);//显示
add(12.2,34.2);//自动类型推导
}
int main(){
test();
}

普通函数与函数模板的区别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include

using namespace std;

int myadd01(int a,int b){
return a+b;
}
template<class T>
T myadd(T a,T b){
return a+b;
}
void test(){
int a=12,b=23;
char c='a';
cout<endl;
cout<endl;
cout<endl;//函数模板自动类型推导,不会发生自动类型转换
cout<int>(a,c)<<endl;//不能类型转换,需要指定类型
}
int main(){
test();
}

image-20191205175241874

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//通过空模板参数调用函数模板
//函数模板也能发生函数重载
#include

using namespace std;

template<class T>
void add(T a,T b){
cout<<"函数模板1"<<endl;
}
template<class T>
void add(T a,T b,T c){
cout<<"函数模板2"<<endl;
}
void add(int a,int b){
cout<<"普通函数"<<endl;
}

void test(){
add(12,30);
add<>(12,30);
add(12,30,23);
}
int main(){
test();
}

函数模板的类对象的对比

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include

using namespace std;

class Person{
public:
Person(int age,string name){
this->age=age;
this->name=name;
}
int age;
string name;
};
template<class T>
bool mycompare(T &a,T &b){
if(a==b){
return true;
}
}
template<> bool mycompare(Person &a,Person &b){
if(a.age==b.age&&a.name==b.name){
return true;
}
}
void test(){
Person p1(12,"java");
Person p2(12,"java");
cout<endl;
}
int main(){
test();
}

类模板

语法

1
2
template<class T>

类模板与函数模板的区别

image-20191205183118841

类模板中成员函数的创建时机是模板调用时才创建

类模板的对象作为函数参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include
#include
using namespace std;


template<class T1,class T2>
class Person{
public:
Person(T1 name,T2 age){
this->name=name;
this->age=age;
}
T1 name;
T2 age;
void showPerson(){
cout<<this->name<<" "<<this->age<<endl;
}
};
//1 指定传入类型
void printPerson(Person<string,int> &p){//1 指定传入类型
p.showPerson();
}
//2 参数模板化
template<class T1,class T2>
void printPerson2(Person &p){//1 指定传入类型
p.showPerson();
}
//3 整个类模板化
template<class T>
void printPerson3(T &p){
p.showPerson();
cout<<typeid(T).name()<<endl;
}
void test(){//类模板的对象做函数的参数
Person p1("java",12);
printPerson(p1);
printPerson2(p1);
printPerson3(p1);
}
int main(){
test();
}

类模板与继承

image-20191205205213805

类模板成员函数类外实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include

using namespace std;

template<class T1,class T2>
class Person{
public:
Person(T1 name,T2 age);
T1 name;
T2 age;
void showPerson();
};
template<class T1,class T2>
Person::Person(T1 name,T2 age){//类模板构造函数类外实现
this->name=name;
this->age=age;
}
template<class T1,class T2>
void Person::showPerson(){//模板类成员函数类外实现
cout<<this->name<<this->age<<endl;
}
void test(){
Person p1("c++",12);
p1.showPerson();

}
int main(){
test();
}

类模板的的分文件编写

1
//将类模板和实现放在同一个文件中并命名为.hpp的文件,然后再.cpp中包含.hpp文件.

image-20191205213840891

1
2
3
4
5
6
7
8
9
10
11
#include

using namespace std;
#include"person.hpp"
void test(){
Person p1("java",12);
p1.showPerson();
}
int main(){
test();
}

全局函数类外实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include

using namespace std;

template<class T1,class T2>//声明模板
class Person; //声明类

template<class T1,class T2>//声明这个函数
void showPerson1(Person p){
cout<endl;
}


template<class T1,class T2>
class Person{
friend void showPerson(Person p){//全局函数类内实现
cout<endl;
}
//加空参数列表
friend void showPerson1<>(Person p);
private:
T1 name;
T2 age;
public:
Person(T1 name,T2 age){
this->name=name;
this->age=age;
}


};
void test(){
Person p1("c++",12);
showPerson(p1);
showPerson1(p1);
}

int main(){
test();
}

本文标题:继承和多态

文章作者:philxling

发布时间:2020年04月10日 - 23:15

最后更新:2020年10月15日 - 12:26

原始链接:http://philxling.club/2020/04/10/c++/4-%E7%BB%A7%E6%89%BF%E5%92%8C%E5%A4%9A%E6%80%81/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

philxling wechat
ex. subscribe to my blog by scanning my public wechat account
-------------本文结束感谢您的阅读-------------
谢谢你给我糖吃!!!
0%