黑马程序员 4 类和对象


4.4友元

友元的目的是让一个函数或者是类 访问另一个函数的私有成员

友元的关键字为 friend

4.4.1全局函数做友元

 1 #include
 2 #include<string>
 3 using namespace std;
 4 
 5 class Building
 6 {
 7     //goodGay全局函数是 Building好朋友,可以访问Buiding中私有成员
 8     friend void goodGay(Building* building);
 9 
10 
11 public:
12     Building()
13     {
14         m_SittingRoom = "客厅";
15         m_BedRoom = "卧室";
16     }
17 
18 
19 public:
20     string m_SittingRoom;//客厅
21 
22 private:
23     string m_BedRoom;//卧室
24 };
25 
26 
27 //全局函数
28 void goodGay(Building *building)
29 {
30     cout << "好基友全局函数 正在访问:" << building->m_SittingRoom << endl;
31     cout << "好基友全局函数 正在访问:" << building->m_BedRoom << endl;
32 }
33 
34 void test01()
35 {
36     Building building;
37     goodGay(&building);
38 }
39 
40 
41 int main()
42 {
43     test01();
44     return 0;
45 }

4.4.2类做友元

 1 #include
 2 #include<string>
 3 using namespace std;
 4 
 5 //类做友元
 6 class Building;
 7 class GoodGay;
 8 
 9 class GoodGay
10 {
11 public:
12 
13     GoodGay();
14 
15     void visit();//参观函数 访问Building 中的属性
16 
17     Building* building;
18 
19 
20 };
21 
22 class Building
23 {
24     //GoodGay类是本来的好朋友,可以访问本类中私有成员
25     friend class GoodGay;
26 
27 public:
28     Building();
29 
30 
31 public:
32     string m_SittingRoom;//客厅
33 private:
34     string m_BedRoom;
35 };
36 
37 //类外写成员函数
38 Building::Building()
39 {
40     m_SittingRoom = "客厅";
41     m_BedRoom = "卧室";
42 }
43 GoodGay::GoodGay()
44 {
45     //创建建筑物对象
46     building = new Building;
47 }
48 
49 void GoodGay::visit()
50 {
51     cout << "好基友正在访问" << building->m_SittingRoom << endl;
52     cout << "好基友正在访问" << building->m_BedRoom << endl;
53 }
54 
55 void test01()
56 {
57     GoodGay gg;
58     gg.visit();
59 }
60 
61 int main()
62 {
63     test01();
64 
65     return 0;
66 }

4.4.3成员函数做友元

 1 #include
 2 #include<string>
 3 using namespace std;
 4 
 5 class Building;
 6 class GoodGay
 7 {
 8 public:
 9 
10     GoodGay();
11 
12     void visit();//让visit函数可以访问Building中私有成员
13     void visit2();//让visit2函数不可以访问Building中的私有成员
14 
15     Building* building;
16 };
17 
18 class Building
19 {
20     //告诉编译器 GoodGay类下的visit成员函数作为本类的好朋友,可以访问私有的成员
21     friend void GoodGay::visit();
22 
23 public:
24     Building();
25 
26 public:
27     string m_SittingRoom;//客厅
28 
29 private:
30     string m_BedRoom;//卧室
31 
32 };
33 
34 //类外实现成员函数
35 Building::Building()
36 {
37     m_SittingRoom = "客厅";
38     m_BedRoom = "卧室";
39 }
40 
41 GoodGay::GoodGay()
42 {
43     building = new Building;
44 }
45 
46 void GoodGay::visit()
47 {
48     cout << "visit函数正在访问:" << building->m_SittingRoom << endl;
49     cout << "visit函数正在访问:" << building->m_BedRoom << endl;
50 }
51 void GoodGay::visit2()
52 {
53     cout << "visit函数正在访问:" << building->m_SittingRoom << endl;
54     //cout << "visit函数正在访问:" << building->m_BedRoom << endl;
55 }
56 
57 void test01()
58 {
59     GoodGay gg;
60     gg.visit();
61     gg.visit2();
62 
63 }
64 
65 int main()
66 {
67     test01();
68 
69     return 0;
70 }

4.5运算符

 运算符重载概念:对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型

4.5.1加号运算符重载

作用:实现两个自定义数据类型相加的运算

总结1:对于内置的数据类型的表达式的运算符是不可能改变的

总结2:不要滥用运算符重载

 1 #include
 2 using namespace std;
 3 //加号运算符重载
 4 
 5 class Person
 6 {
 7 public:
 8 
 9     //1.成员函数重载+号
10     //Person operator+(Person& p)
11     //{
12     //    Person temp;
13     //    temp.m_A = this->m_A + p.m_A;
14     //    temp.m_B = this->m_B + p.m_B;
15     //    return temp;
16     //}
17     int m_A;
18     int m_B;
19 };
20 //2.全局函数重载+号
21 Person operator+(Person& p1, Person& p2)
22 {
23     Person temp;
24     temp.m_A = p1.m_A + p2.m_A;
25     temp.m_B = p1.m_B + p2.m_B;
26     return temp;
27 }
28 //函数重载的版本
29 Person operator+(Person& p1, int num)
30 {
31     Person temp;
32     temp.m_A = p1.m_A + num;
33     temp.m_B = p1.m_B + num;
34     return temp;
35 }
36 
37 void test01()
38 {
39     Person p1;
40     p1.m_A = 10;
41     p1.m_B = 10;
42     Person p2;
43     p2.m_A = 10;
44     p2.m_B = 10;
45 
46     //成员函数重载本质调用
47     //Person p3 = p1.operator+(p2);
48     
49     //全局函数重载的本质调用
50     Person p3 = operator+(p1, p2);
51 
52     Person p3 = p1 + p2;
53     //运算符重载 也可以发生函数重载
54 
55     Person p4 = p1 + 10;//Person +int
56 
57     cout << "p3.m_A=" << p3.m_A << endl;
58     cout << "p3.m_B=" << p3.m_B << endl;
59     cout << "p4.m_A=" << p4.m_A << endl;
60     cout << "p4.m_B=" << p4.m_B << endl;
61     
62 
63 }
64 
65 //1.成员函数重载+号
66 
67 //2.全局函数重载+号
68 
69 int main()
70 {
71     test01();
72     return 0;
73 }

4.5.2左移运算符重载

 1 #include
 2 using namespace std;
 3 
 4 //左移运算符重载
 5 
 6 class Person
 7 {
 8 public:
 9     //利用成员函数重载 左移运算符 p.operator<<(cout) 简化版本 p<10     //不会利用成员函数重载<<运算符,因为无法实现cout在左侧
11 
12 
13     int m_A;
14     int m_B;
15 };
16 //只能利用全局函数重载左移运算符
17 ostream &operator<<(ostream &cout, Person &p)//本质 operator<<(cout ,p)简化 cout<
18 {
19     cout << "m_A=" << p.m_A << "m_B=" << p.m_B;
20     return cout;
21 }
22 
23 
24 void test01()
25 {
26     Person p;
27     p.m_A = 10;
28     p.m_B = 10;
29     
30     cout << p << "hello world " << endl;
31 
32 }
33 
34 int main()
35 {
36     test01();
37 
38     return 0;
39 }

4.5.3自增运算符重载

 1 #include
 2 using namespace std;
 3 //重载自增运算符
 4 //自定义整型
 5 
 6 class MyInteger
 7 {
 8     friend ostream& operator<<(ostream& cout, MyInteger myint);
 9 public:
10     MyInteger()
11     {
12         m_Num = 0;
13     }
14 
15     //重载前置++运算符 返回引用为了一直对一个数据进行递增操作
16     MyInteger& operator++()
17     {
18         //先进行++运算
19         m_Num++;
20 
21         //再将自身做范围
22         return *this;
23     }
24 
25     //重载后置++运算符
26 
27     //void operator++(int) int代表占位参数,可以用于区分前置和后置递增
28     MyInteger operator++(int)
29     {
30         //先 记录当时结果
31         MyInteger temp = *this;
32         //后 递增
33         m_Num++;
34         //最后将记录结果做返回
35         return temp;
36     }
37 
38 private:
39     int m_Num;
40 };
41 
42 //重载一下左移运算符
43 ostream& operator<<(ostream& cout, MyInteger myint)
44 {
45     cout << myint.m_Num;
46     return cout;
47 }
48 
49 void test01()
50 {
51     MyInteger myint;
52 
53     cout << ++(++myint) << endl;
54     cout << myint << endl;
55 }
56 
57 void test02()
58 {
59     MyInteger myint;
60 
61     cout << myint++ << endl;
62     cout << myint << endl;
63 }
64 
65 int main()
66 {
67     test01();
68     test02();
69 
70     //int a = 0;
71     //
72     //cout << ++(++a) << endl;
73     //cout << a << endl;
74 
75 
76     return 0;
77 }

4.5.4关系运算符重载

 1 #include
 2 using namespace std;
 3 //赋值运算符重载
 4 class Person
 5 {
 6 
 7 public:
 8 
 9     Person(int age)
10     {
11         m_Age=new int(age);
12     }
13 
14     ~Person()
15     {
16         if (m_Age != NULL)
17         {
18             delete m_Age;
19             m_Age = NULL;
20         }
21     }
22     //重载赋值运算符
23     Person& operator=(Person& p)
24     {
25         //编译器提供浅拷贝
26         //m_Age = p.m_Age;
27 
28         //应该先判断是否有属性在堆区,如果有,先释放干净,然后再深拷贝
29         if (m_Age != NULL)
30         {
31             delete m_Age;
32             m_Age = NULL;
33         }
34         //深拷贝
35         m_Age = new int(*p.m_Age);
36 
37         //返回对象本身
38         return *this;
39     }
40 
41     int *m_Age;
42 
43 };
44 
45 void test01()
46 {
47     Person p1(18);
48 
49     Person p2(20);
50 
51     Person p3(30);
52 
53     p3=p2 = p1;//赋值操作
54 
55     cout << "p1的年龄为:" << *p1.m_Age << endl;
56     cout << "p2的年龄为:" << *p2.m_Age << endl;
57     cout << "p3的年龄为:" << *p3.m_Age << endl;
58 }
59 
60 int main()
61 {
62     test01();
63 
64     /*int a = 10;
65     int b = 20;
66     int c = 30;
67 
68     c = b = a;
69 
70     cout << "a=" << a << endl;
71     cout << "b=" << b << endl;
72     cout << "c=" << c << endl;*/
73 
74 
75 
76 
77 
78     system("pause");
79     return 0;
80 }

4.5.5关系运算符重载

 1 #include
 2 #include<string>
 3 using namespace std;
 4 
 5 //重载关系运算符
 6 
 7 class Person
 8 {
 9 public:
10     Person(string name, int age)
11     {
12         m_Name = name;
13         m_Age = age;
14     }
15     //重载==号
16 
17     bool operator==(Person &p)
18     {
19         if (this->m_Name == p.m_Name && this->m_Age == p.m_Age)
20         {
21             return true;
22         }
23         return false;
24     }
25     bool operator!=(Person& p)
26     {
27         if (this->m_Name == p.m_Name && this->m_Age == p.m_Age)
28         {
29             return false;
30         }
31         return true;
32     }
33 
34     string m_Name;
35     int m_Age;
36 };
37 
38 void test01()
39 {
40     Person p1("Tom", 18);
41 
42     Person p2("Tom", 18);
43 
44     if (p1 == p2)
45     {
46         cout << "p1和p2是相等的" << endl;
47     }
48 
49 
50 }
51 
52 int main()
53 {
54     test01();
55     return 0;
56 }

4.5.4函数调用运算符重载

 1 #include
 2 #include<string>
 3 using namespace std;
 4 //函数调用运算符重载
 5 
 6 //打印输出类
 7 class MyPrint
 8 {
 9 public:
10     //重载函数调用运算符
11     void operator()(string test)
12     {
13         cout << test << endl;
14     }
15 };
16 
17 void Myprint02(string test)
18 {
19     cout << test << endl;
20 }
21 
22 void test01()
23 {
24     MyPrint myPrint;
25 
26     myPrint("hello world");//由于使用起来非常类似于函数调用,因此成为仿函数
27 
28     Myprint02("hello world");
29 }
30 //仿函数非常灵活,没有固定写法
31 //加法类
32 
33 class MyAdd
34 {
35 public:
36 
37     int operator()(int num1,int num2)
38     {
39         return num1 + num2;
40     }
41 };
42 
43 void test02()
44 {
45     MyAdd myadd;
46     int ret=myadd(100, 100);
47     cout << "ret=" << ret << endl;
48 
49     //匿名函数对象
50     cout << MyAdd()(100, 100) << endl;
51 }
52 
53 int main()
54 {
55     //test01();
56     test02();
57     return 0;
58 }

4.6继承

4.6.1继承的基本语法

  1 #include
  2 using namespace std;
  3 
  4 //普通实现页面
  5 
  6 //Java页面
  7 //
  8 //class Java
  9 //{
 10 //public:
 11 //    void header()
 12 //    {
 13 //        cout << "首页、公开课、登录、注册...(公共头部)" << endl;
 14 //    }
 15 //    void footer()
 16 //    {
 17 //        cout << "帮助中心、交流合作、站内地图..(公共底部)." << endl;
 18 //
 19 //    }
 20 //    void left()
 21 //    {
 22 //        cout << "Java、Python、C++、...(公共分类列表" << endl;
 23 //    }
 24 //    void content()
 25 //    {
 26 //        cout << "Java学科视频" << endl;
 27 //    }
 28 //};
 29 //
 30 ////Python页面
 31 //class Python
 32 //{
 33 //public:
 34 //    void header()
 35 //    {
 36 //        cout << "首页、公开课、登录、注册...(公共头部)" << endl;
 37 //    }
 38 //    void footer()
 39 //    {
 40 //        cout << "帮助中心、交流合作、站内地图..(公共底部)." << endl;
 41 //
 42 //    }
 43 //    void left()
 44 //    {
 45 //        cout << "Java、Python、C++、...(公共分类列表" << endl;
 46 //    }
 47 //    void content()
 48 //    {
 49 //        cout << "Python学科视频" << endl;
 50 //    }
 51 //};
 52 ////C++页面
 53 //class CPP
 54 //{
 55 //public:
 56 //    void header()
 57 //    {
 58 //        cout << "首页、公开课、登录、注册...(公共头部)" << endl;
 59 //    }
 60 //    void footer()
 61 //    {
 62 //        cout << "帮助中心、交流合作、站内地图..(公共底部)." << endl;
 63 //
 64 //    }
 65 //    void left()
 66 //    {
 67 //        cout << "Java、Python、C++、...(公共分类列表" << endl;
 68 //    }
 69 //    void content()
 70 //    {
 71 //        cout << "C++学科视频" << endl;
 72 //    }
 73 //};
 74 
 75 //继承实现页面
 76 
 77 //公共页面类
 78 class BasePage
 79 {
 80 public:
 81     void header()
 82     {
 83         cout << "首页、公开课、登录、注册...(公共头部)" << endl;
 84     }
 85     void footer()
 86     {
 87         cout << "帮助中心、交流合作、站内地图..(公共底部)." << endl;
 88 
 89     }
 90     void left()
 91     {
 92         cout << "Java、Python、C++、...(公共分类列表" << endl;
 93     }
 94 };
 95 //Java页面
 96 class JAVA :public BasePage
 97 {
 98 public:
 99     void content()
100     {
101         cout << "Java学科视频" << endl;
102     }
103 };
104 class Python :public BasePage
105 {
106 public:
107     void content()
108     {
109         cout << "Python学科视频" << endl;
110     }
111 };
112 class CPP :public BasePage
113 {
114 public:
115     void content()
116     {
117         cout << "C++学科视频" << endl;
118     }
119 };
120 
121 void test01()
122 {
123     cout << "Java下载视频页面如下:" << endl;
124     JAVA ja;
125     ja.header();
126     ja.footer();
127     ja.left();
128     ja.content();
129 
130     cout << "--------------" << endl;
131     cout << "Python下载视频页面如下:" << endl;
132     Python py;
133     py.header();
134     py.footer();
135     py.left();
136     py.content();
137 
138     cout << "--------------" << endl;
139     cout << "C++下载视频页面如下:" << endl;
140     CPP cpp;
141     cpp.header();
142     cpp .footer();
143     cpp.left();
144     cpp.content();
145 }
146 
147 
148 
149 
150 int main()
151 {
152     test01();
153     return 0;
154 }