C++:05.虚继承、虚函数、模板函数

1. 属性初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
class Student: public Person{
private:
// char* courseName;
Course course;
public:
Student(char* name,int age,char* courseName):Person(name,age),course(courseName){ // 初始化父类的属性
// this->courseName = courseName;
}

void print(){
cout << name << "," << age << "," << course._name() << endl;
}
};

2. 多继承,(在 java 里面是不允许多继承的, c++ 是可以的, 但是你也不能有二义性(歧义))

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
class Person {
protected:
char *name;
public:
Person(char *name) {
this->name = name;
}

char *_name() {
return this->name;
}
};

class Child {
int age;
public:
Child(int age) {
this->age = age;
}

int _age() {
return age;
}
};

class Student : public Person, public Child { // 多继承,并没有实现
public:
Student(char *name, int age) : Person(name), Child(age) {

}
};

3. 虚继承(二义性)

作用:解决二义性确保继承过来的相同属性或者函数,只存在一份拷贝

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class A {
public:
char *name;
};

class B : virtual public A { // 确保继承过来的相同属性或者函数,只存在一份拷贝

};

class C : virtual public A {

};

class D : public B, public C {

};
1
2
3
4
int main(){
D d;
d.name = "east"; // 如果不用虚继承,会报错:不明确 name 是 B 的 还是 C 的
}

4. c++ 中的多态

c++ 中的多态默认情况下不存在,如果需要使用多态,一定要加上virtual 关键字

c++中多态分两种:

  1. 动态多态:子父类继承
  2. 静态多态:方法的重载
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Activity {
public:
// 如果没有 virtual 关键字就没有多态
virtual void onCreate() { // 支持多态,虚函数
cout << "Activity 中的 onCreate" << endl;
}
};

class MainActivity : public Activity {
public:
void onCreate() override {
cout << "MainActivity 中的 onCreate" << endl;
}
};

调用:

1
2
Activity *activity1 = new MainActivity();
startActivity(activity1);

5. 纯虚函数(类似于:java 中的 抽象类,接口)

如果全部都是纯虚函数就类似 java 中的 接口,否则类似 抽象类

virtual void click() = 0; // 必须要加 = 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
class BaseActivity{
public:
void onCreate(){ // 普通函数
initView();
initData();
}

// 子类必须要实现
virtual void initData() = 0; // 虚函数,没有实现的,类似于 java 中的抽象方法,如果子类不实现会报错

virtual void initView() = 0;
};

// 如果不实现父类的纯虚函数,那么 MainActivity 也会变成抽象类,抽象类不允许实例化
class MainActivity:public BaseActivity{
void initData() override{
cout << "initData" << endl;
}

void initView() override {
cout << "initView" << endl;
}
};

class ClickListener{ // 所有的函数都是虚函数,那么就可以认为是接口
public:
virtual void click() = 0; // 必须要加 = 0
};

6. 构造函数和析构函数

  • 构造函数:先父类 -> 再子类
  • 析构函数: 先子类 -> 再父类
1
2
3
4
5
6
int main(){
// 构造函数:先父类 -> 再子类
// 析构函数: 先子类 -> 再父类
Student* stu = new Student("East",25);
delete (stu);
}

7. 模板函数(java 中的泛型)

7.1.定义:

template <typename T> // 模板函数的定义(不能有分号)

1
2
3
4
template <typename T>  // 模板函数的定义(不能有分号)
T add(T number1,T number2){
return number1+number2;
}

7.2. 当普通函数和模板函数同时存在时,优先会调用普通函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
template <typename T>
T add(int number1, int number2){
cout << "模板函数被调用" << endl;
return number1+number2;
}

int add(int number1,int number2){
cout << "int add 被调用" << endl;
return number1+number2;
}

// so 是很难被反编译,比 java 安全为啥
// samll 语法

int main(){
int sum1 = add(1,2);

double sum2 = add(1.0,2.0);

float sum3 = add(1.0f,2.0f);

cout << sum1 << " , " << sum2 << endl;
}

打印结果:

1
2
3
4
int add 被调用
int add 被调用
int add 被调用
3 , 3

8.模板类

语法跟模板函数非常相似

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
template <typename T>
class Callback{
public:
void onError(){

}

void onSucceed(T result){
cout << result << endl;
}
};

// 模板类继承
// 如果子类不是模板类
class HttpCallback : public Callback<int>{

};

// 子类还是模板类
template <typename T>
class HttpCallback : public Callback<T>{

};
-------------本文结束感谢您的阅读-------------
坚持原创技术分享,您的支持将鼓励我继续创作!
0%