C++面向对象进阶

2

C++面向对象进阶

  前面介绍了面向对象的三种访问控制权限。今天带小伙们看一看C++面向对象中的static,const,friend关键字。

static关键字

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
#include<iostream>
using namespace std;


class Person {

public:
//static修饰的成员变量称为静态成员变量,其特点是所有对象共享一份数据,也可称为类成员变量,说明这个成员变量不属于某一个对象,而是属于这个类。
//在编译阶段分配内存,并且要在类内声明,在类外定义
static string name;

static int age;

int score = 100;

//static修饰的成员方法称为静态成员方法,其特点是所有对象共享一个函数,也可称为类成员函数,注意类成员函数只能访问类成员变量,不可以访问普通成员变量。
static string getName() {
return name;
}

static int getAge() {
return age;
}

int getScore() {
return score;
}
};

string Person::name = "程序员";
int Person::age = 24;

int main() {

//使用静态成员方法时可以通过对象名.静态成员变量名,也可以通过类名::静态成员变量名,因为所有对象都拥有同一份数据,因此为了区分推荐使用类名::静态成员变量名
cout << "我的名字是:" << Person::name << " 我的年龄是:" << Person::age << endl;

Person p1;
p1.name = "小学生";
p1.age = 8;
p1.score = 100;

Person p2;
p2.name = "高中生";
p2.age = 18;
p2.score = 150;

//因为p1和p2拥有同一个名字和年龄,因此p1的名字和年龄都会变成和p2相同的数据,但是分数不会,因为分数是普通成员变量,每个对象都具有一份独特的数据。
cout << "我的名字是:" << p1.name << " 我的年龄是:" << p1.age << " 我的成绩是:" << p1.score << endl;
cout << "我的名字是:" << p2.name << " 我的年龄是:" << p2.age << " 我的成绩是:" << p2.score << endl;
cout << "我的名字是:" << Person::name << " 我的年龄是:" << Person::age << endl;
//访问成员方法是和成员变量相同,但是要注意静态成员方法不可以访问普通成员变量,在getAge成员方法中,不能够访问score普通成员变量。
cout << "我的名字是:" << p1.getName() << " 我的年龄是:" << p1.getAge() << endl;
cout << "我的名字是:" << Person::getName() << " 我的年龄是:" << Person::getAge() << endl;

return 0;
}

1

const关键字

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
#include<iostream>
using namespace std;


class Person {

private:
string name = "xxx";
mutable int arms = 2;

public:
void setName(string name) {
this->name = name;
}

//在成员方法的参数列表后面写上const关键字,称为常函数,此时相当于给this指针前面加入const关键字,因此指针指向的内容也不能发生改变,所以在常函数中不能够修改变量的值。
//如果想要修改,则需要在对应的成员变量前加入mutable关键字。
void setArms(int arms) const{
this->arms = arms;
}

string getName() {
return name;
}

int getArms() const{
return arms;
}
};

int main() {

Person p1;
p1.setName("程序员");
p1.setArms(2);
cout << "我的名字是:" << p1.getName() << "我的手臂个数为:" << p1.getArms() << endl;

//在声明对象前加const关键字,说明该对象为常对象,常对象只能调用常函数,也只能修改加入mutable修饰的成员变量。
const Person p2;
p2.setArms(1);
cout << "我的手臂个数为:" << p2.getArms() << endl;

return 0;
}

1

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
27
28
29
30
31
32
33
34
35
36
37
#include<iostream>
using namespace std;


class Person {

//通过将全局函数的声明写入类内,并在前面加上friend关键字,说明这个全局函数是这个类的好朋友,称作友元,可以访问其私有成员。
friend int getAge(Person& p);
friend void setAge(Person& p, int age);

public:
string name;

private:
int age;

};

//setAge是全局函数,根据访问控制权限,在类外无法访问到类内的私有成员
void setAge(Person& p, int age) {
p.age = age;
}

//getAge是全局函数,根据访问控制权限,在类外无法访问到类内的私有成员
int getAge(Person& p) {
return p.age;
}

int main() {

Person p1;
p1.name = "程序员";
setAge(p1, 24);
cout << "我的名字是:" << p1.name << " 我的年龄是:" << getAge(p1) << endl;

return 0;
}

1

类作为友元

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
#include<iostream>
using namespace std;


class Person {

//将Friend类的声明写入类内,并在前面加上friend关键字,说明Friend是这个类的好朋友,称作友元,可以访问其私有成员。
friend class Friend;

public:
string name;

private:
int age;

};

//根据访问控制权限,Friend类无法访问Person类的私有成员
class Friend {

public:
static void setAge(Person& p, int age) {
p.age = age;
}

static int getAge(Person& p) {
return p.age;
}
};

int main() {

Person p1;
p1.name = "程序员";
Friend::setAge(p1, 24);
cout << "我的名字是:" << p1.name << " 我的年龄是:" << Friend::getAge(p1) << endl;

return 0;
}

1

成员函数作为友元

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
#include<iostream>
using namespace std;

//要将Person的声明写在Friend的定义前面,要告诉编译器后面有Person类的定义,这样参数列表中才可以写入Person,否则编译器也会报错。
class Person;

//注意写法,要将Friend定义在前面,如果将Person写在前面,则编译器不知道Friend::setAge函数是什么。
class Friend {

public:
static void setAge(Person& p, int age);
static int getAge(Person& p);
};


class Person {

//通过将成员函数的声明写入类内,并在前面加上friend关键字,说明这个成员函数是这个类的好朋友,称作友元,可以访问其私有成员。
//要注意成员函数的前面要写清作用域,否则会当作全局函数作为友元。
friend void Friend::setAge(Person& p, int age);
friend int Friend::getAge(Person& p);

public:
string name;

private:
int age;

};

//要注意Friend成员函数要在类外实现,且要放在Person类的定义之后,否则编译器只知道Person类的存在,却不知道Person类中有哪些成员,也会报错。
void Friend::setAge(Person& p, int age) {
p.age = age;
}

int Friend::getAge(Person& p) {
return p.age;
}

int main() {

Person p1;
p1.name = "程序员";
Friend::setAge(p1, 24);
cout << "我的名字是:" << p1.name << " 我的年龄是:" << Friend::getAge(p1) << endl;

return 0;
}

1

C++小结

  今天的内容也非常重要,static关键字,要记得它不属于某一个对象,而是属于整个类,因此在以后的访问中尽量使用类名的方式进行访问,友元的三种使用方法大家要记得,尤其是第三种非常复杂,牵扯到函数和类的声明等问题,小伙伴们一定要理解它。

-------------本文结束感谢您的阅读-------------
0%