类的友元

1.有元是C++提供的一种破坏数据封装和数据隐藏的机制

2.通过将一个模板声明为另一个模板的友元,一个模块可以引用到另一个模块中本是隐藏的信息

3 . 可以使用友元类和友元函数


以一个例子来表示:关键字是`friend`
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<iostream>
#include<cmath>
using namespace std;
class Point{
private:
int x,y;
public:
Point(int x=0,int y=0){
this->x=x;
this->y=y;
}
int getX(){return x;}
int getY(){return y;}
friend double dist(Point &a,Point &b);
}
double dist(Point& a,Point &b){
double x=a.x-b.x;
double y=a.y-b.y;
return (sqrt(x*x+y*y));
}
int main(void){
Point p1(1,1),p2(4,5);
cout<<"The distance is:";
cout<<dist(p1,p2)<<endl;
return 0;
}

dist 函数中 x为类中private,本来是不该被访问的(只能通过getX函数来访问),但是有friend,所以可以使用

类的继承

为什么要用继承

&emsp;定义一个Student类,如果要对该类进行增加private中变量,可以定义一个新类Graduate Student来继承 Student类,
class GraduateStudent:public Student
只需要在private中增加新的变量名即可,并且原来Student中变量和函数也会在新的类中使用
被继承的类称为基类(或者父类) ,这里的Student 就是父类
示例截图.png

构造函数与析构函数的继承

1、 构造函数不被继承,派生类的构造函数只负责初始化在派生类中声明的数据成员
2、派生类构造函数只负责在派生类中声明的数据成员
3、派生类的构造函数必须通过调用基类的某个构造函数来初始化基类子对象
4、不管派生类在类层次上有多少个祖先类,其构造函数只能用其 直接基类 的构造函数

派生类构造函数

派生类构造函数应该包括初始化本身数据和基类子对象的形式参数
形式:

1
2
3
派生类名(参数表):基类名(基类构造函数参数表){
派生类构造函数体
}

举例:
派生类Rectangle的构造函数的实现

1
2
3
4
Rectangle::Rectangle(int x,int y,iny w,int h):Point(x, y){
width=w;
heigh=h;
}

派生类析构函数

1、析构函数也不被继承,派生类自行声明
2、声明方法与一般(无继承关系时的)类的析构函数相同
3、不需要显示的调用基类的析构函数,系统自动的隐式调用
4、析构函数的调用与构造函数相反

课后作业

屏幕截图 2023-01-27 165827.png

答案

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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#include<iostream>
#include<string.h>
#define PAI 3.1415926
using namespace std;
class Shape {
private:
string color;
public:
Shape();
Shape(string c);
~Shape();
string getColor();
void setColor(string c);
double getArea();
void display();
};
class Circle :public Shape {
private:
double radius;
public:
Circle();
Circle(string c, double r);
~Circle();
void setRadius(double r);
double getRadius();
double getArea();
void display();
};
class Rectangle :public Shape {
private:
double width, height;
public:
Rectangle();
Rectangle(string c, double w, double h);
~Rectangle();
void setWidth(double w);
void setHight(double h);
double getWidth();
double getHeight();
double getArea();
void display();
};
class RoundRectangle :public Rectangle {
private:
double roundRadius;
public:
RoundRectangle();
RoundRectangle(string c, double w, double h, double r);
~RoundRectangle();
void setRoundRadius(double r);
double getRoundRadius();
double getArea();
void display();
};
Shape::Shape() {
this->color = "white";
cout << "Shape defauly contructor called" << endl;
}
Shape::Shape(string c) {
color = c;
cout << "Shape contructor called" << endl;
}
Shape::~Shape() {
cout << "Shape default destructor called" << endl;
}
void Shape::setColor(string c) {
color = c;
}
string Shape::getColor() {
return color;
}
double Shape::getArea() {
return 0;
}
void Shape::display() {
cout << "[Shape Object] color=" << getColor() << "area" << getArea() << endl;

}
Circle::Circle() {
radius = 1;
cout << "Circle default Constructor called" << endl;
}
Circle::Circle(string c, double r) :Shape(c), radius(r) {
cout << "Circle constructor called" << endl;
}
Circle::~Circle() {
cout << "Circle destructor called" << endl;
}
void Circle::setRadius(double r) {
this->radius = r;
}
double Circle::getRadius() {
return radius;
}
double Circle::getArea() {
return PAI * radius * radius;
}
void Circle::display() {
cout << "[Circle Object] color =" << getColor() << endl;
}
//无参构造函数会自动调用父类的构造函数(Shape)的无参构造函数
Rectangle::Rectangle() {
this->width = 1;
this->height = 1;
cout << "Rectangle default constructor called" << endl;
}
Rectangle::Rectangle(string c, double w, double h):Shape(c) {
this->width = w;
this->height=h;
cout << "Rectangle constructor called" << endl;
}
Rectangle::~Rectangle() {
cout << "Rectangle destructor called." << endl;
}
void Rectangle::setWidth(double w) {
this->width = w;
}
void Rectangle::setHight(double h) {
this->height = h;
}
double Rectangle::getHeight() {
return height;
}
double Rectangle::getWidth() {
return width;
}
double Rectangle::getArea() {
return width * height;
}
void Rectangle::display() {
cout << "[Rectangle Object] color=" << getColor() << "area=" << getArea() << endl;
}
RoundRectangle::RoundRectangle() {
this->roundRadius = 1;
cout<< "RoundRectangle default constructor called" << endl;
}
RoundRectangle::RoundRectangle(string c, double w, double h, double r) : Rectangle(c,w, h){
this->roundRadius = r;
cout<< "RoundRectangle constructor called" << endl;
}
RoundRectangle::~RoundRectangle() {
cout << "RoundRectangle destructor called." << endl;
}
double RoundRectangle::getRoundRadius() {
return roundRadius;
}
double RoundRectangle::getArea() {
return getWidth() * getHeight() - (roundRadius * roundRadius * 4 - PAI * roundRadius);
}
void RoundRectangle::display() {
cout << "[RoundRectangle Object] color=" << getColor() << "area=" << getArea() << endl;
}
int main(void) {
Shape shape1, shape2("red");
shape1.display();
shape2.display();
cout << endl;
Rectangle rect1, rect2("black", 5, 4);
rect1.display();
rect2.display();
RoundRectangle round1, round2("green", 5, 4, 0.5);
round1.display();
round2.display();
cout << endl;
cout << "程序结束!----------------------------";
cout << endl;
return 0;
}