类和对象 3#
面向对象程序设计中最重要的一个概念是继承。继承允许我们依据另一个类来定义一个类,这使得创建和维护一个应用程序变得更容易。这样做,也达到了重用代码功能和提高执行效率的效果。
当创建一个类时,您不需要重新编写新的数据成员和成员函数,只需指定新建的类继承了一个已有的类的成员即可。这个已有的类称为基类,新建的类称为派生类。
子类的访问权限#
|
public |
protected |
private |
public |
yes |
yes |
yes |
protected |
yes |
yes |
no |
private |
no |
no |
no |
对外的访问权限#
|
public |
protected |
private |
public |
public |
protected |
private |
protected |
protected |
protected |
private |
private |
no |
no |
no |
菱形继承(A->D, B->D, C->(A,B))#
class D{......};
class B: public D{......};
class A: public D{......};
class C: public B, public A{.....};
这个继承会使 D 创建两个对象,要解决上面问题就要用虚拟继承格式
格式:class 类名: virtual 继承方式 父类名
class D{......};
class B: virtual public D{......};
class A: virtual public D{......};
class C: public B, public A{.....};
虚继承–(在创建对象的时候会创建一个虚表)在创建父类对象的时候
A:virtual public D
B:virtual public D
访问控制和继承#
派生类可以访问基类中所有的非私有成员。因此基类成员如果不想被派生类的成员函数访问,则应在基类中声明为 private。
我们可以根据访问权限总结出不同的访问类型,如下所示:
访问 |
public |
protected |
private |
同一个类 |
yes |
yes |
yes |
派生类 |
yes |
yes |
no |
外部的类 |
yes |
no |
no |
一个派生类继承了所有的基类方法,但下列情况除外:
- 基类的构造函数、析构函数和拷贝构造函数
- 基类的重载运算符
- 基类的友元函数
当使用不同类型的继承时,遵循以下几个规则:
- 公有继承(public):当一个类派生自公有基类时,基类的公有成员也是派生类的公有成员,基类的保护成员也是派生类的保护成员,基类的私有成员不能直接被派生类访问,但是可以通过调用基类的公有和保护成员来访问。
- 保护继承(protected): 当一个类派生自保护基类时,基类的公有和保护成员将成为派生类的保护成员。
- 私有继承(private):当一个类派生自私有基类时,基类的公有和保护成员将成为派生类的私有成员。
运算符重载#
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
|
#include<iostream>
using namespace std;
class Point {
public:
Point() {}
Point(int x, int y) : x(x), y(y) {}
Point(const Point &obj) : x(obj.x), y(obj.y) {
cout << "copy constructor" << endl;
}
int operator()(int num) {
return this->x + this->y + num;
}
int operator[](string str) {
if (str == "x") return this->x;
if (str == "y") return this->y;
return 0;
}
Point operator-(const Point &a) {
Point ret;
ret.x = this->x - a.x;
ret.y = this->y - a.y;
return ret;
}
friend ostream &operator<<(ostream &, const Point &);
friend Point operator+(const Point &, const Point &);
private:
int x, y;
};
Point operator+(const Point &a, const Point &b) {
Point ret;
ret.x = a.x + b.x;
ret.y = a.y + b.y;
return ret;
}
ostream &operator<<(ostream &output, const Point &a) {
output << "<class Point>(" << a.x << ", " << a.y << ")";
return output;
}
int main() {
Point a(2, 4), b(5, 3);
Point c = a + b;
Point d = a + b + c;
Point e = d - b;
cout << a << endl;
cout << b << endl;
cout << c << endl;
cout << d << endl;
cout << e << endl;
return 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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
#include <iostream>
#include <algorithm>
using namespace std;
class intArray {
private:
int n;
int *p;
public:
intArray(int n) : n(n) {
this->p = new int[n];
}
intArray(const intArray &obj) : n(obj.n) {
this->p = new int[n];
for (int i = 0; i < n; i++) {
this->p[i] = obj.p[i];
}
}
int size() {
return n;
}
int find(int num) {
for (int i = 0; i < n; i++) {
if (p[i] == num) return i;
}
return -1;
}
void sort(int op) {
if (op) std::sort(p, p + n);
else std::sort(p, p + n, [](int a, int b) {return a > b;});
return ;
}
void reverse() {
std::reverse(p, p + n);
return ;
}
int &operator[](int ind) {
if (ind < 0) return this->p[n + ind];
return this->p[ind];
}
void operator+=(int num) {
for (int i = 0; i < n; i++) {
this->p[i] += num;
}
return ;
}
intArray &operator++() {
for (int i = 0; i < n; i++) {
this->p[i]++;
}
return *this;
}
intArray operator++(int x) {
intArray ret = *this;
for (int i = 0; i < n; i++) {
this->p[i]++;
}
return ret;
}
friend ostream &operator<<(ostream &, const intArray &);
~intArray() {
delete[] this->p;
}
};
ostream &operator<<(ostream &output, const intArray &a) {
output << "<class intArray>:";
for (int i = 0; i < a.n; i++) {
output << " " << a.p[i];
}
return output;
}
int main() {
intArray a(10);
for (int i = 0; i < 10; i++) {
a[i] = i;
}
cout << a.size() << endl;
cout << a.find(3) << endl;
cout << a[4] << endl;
cout << a[-2] << endl;
a += 5;
cout << a << endl;
a.sort(1);
cout << a << endl;
a.sort(0);
cout << a << endl;
a.reverse();
cout << a << endl;
cout << (a++) << endl;
cout << (++a) << endl;
return 0;
}
|