对c++友元函数的认识

     今天做了一道模拟String字符串相加操作符重载的题,对友元的概念不是太清楚,通过看《C++ Primer》和自己的实践对友元这个概念理解了下,写个小总结在这里

友元,这个概念是这对类来说的。一般指的是对一个类,如果有外部函数想要访问这个类中已经封装好的一些数据(比如私有的数据成员),可以将外部函数在类中声明下,

利用关键字friend声明为自己的友元函数即可。

需要注意的两个地方

1、类中声明的友元函数,不是一个普通意义上的声明,即没有作用域等概念,纯粹是类为了说“这个函数是我的朋友”而已,所以其他地方想要调用这个友元函数,则需要

正常普通的声明下,即在调用前需要像普通函数那样声明(即使在类中使用也不例外)

2、一旦被类声明为友元函数,他就可以访问类中的私有成员

3、友元函数不受到类中public/private/protected等访问控制符的限制,即他不属于类的成员函数,这点是要区别开的,这有点想钩子

 

这里贴出今天练习的代码:

 1 #include <stdlib.h>
 2 #include <stdio.h>
 3 #include <iostream>
 4 #include <string.h>
 5 using namespace std;
 6 
 7 // 1、编程语言中的访问控制符如public、protected和private等等是针对此类外的类型、对象来说的。
 8 // 2、在类的方法成员内部(包括构造函数)访问同一个类对象的私有成员时,有些访问控制符是不起作用的,它们在同一个域内。
 9 // 3、通过上面的代码,突然想到在构造函数中的this岂不也是一个类对象,它就能访问本类的私有成员"_price"!所以private是对“外人(如main中)”或者“自家人(A)在外地(main)”来说的。
10 class MyString
11 {
12     friend MyString & operator+(MyString &left,MyString &right);  // 如果不想让自己的数据成员变成public可以讲必须访问的外部函数
13     // 声明为本类的友元函数,这样,就能使得外部的函数访问类的私有数据成员了。友元函数必须和类声名在同一个文件中。
14 public:
15     MyString(const char *s)
16     {
17         str = new char[strlen(s) + 1];
18         strcpy(str, s);
19     }
20     ~MyString()
21     {
22         delete[] str;
23         str = nullptr;
24     }
25     MyString &operator=(MyString &string)
26     {
27         if (this == &string)
28         {
29             return *this;
30         }
31         if (str != nullptr)
32         {
33             delete[] str;
34         }
35         str = new char[strlen(string.str) + 1];
36         strcpy(str, string.str);
37         return *this;
38     }
39     // MyString &operator+(MyString &string)
40     // {
41     //     char *temp = str;
42     //     str = new char[strlen(temp) + strlen(string.str) + 1];  // 也就是说现在证实了我的想法:在本类的复制构造函数,赋值函数,已经操作重载函数中
43     //     // 可以访问作为参数传递进来的本类实例对象的私有数据成员,比喻string.str这个私有成员
44     //     strcpy(str, temp);
45     //     delete[] temp;
46     //     strcat(str, string.str);
47     //     return *this;
48     // }
49     // Mystring &operator+(MyString &string)
50     // {
51     //     MyString *pString = new MyString("");
52     //     pString->str = new char[strlen(str) + strlen(string.str) + 1];
53     //     strcpy(pString->str, str);
54     //     strcat(pString->str, string.str);
55     //     retrun *pString;
56     // }
57     void print()
58     {
59         cout << str << endl;
60     }
61 
62 private:
63     char *str;
64 };
65 
66 MyString & operator+(MyString &left,MyString &right)
67 {
68     MyString *pString = new MyString("");
69     pString->str = new char[strlen(left.str) + strlen(right.str) + 1];
70     strcpy(pString->str, left.str);
71     strcat(pString->str, right.str);
72     return *pString;
73 }
74 
75 
76 int main()
77 {
78     MyString a("hello ");
79     MyString b("world");
80     MyString c("");
81     c = c + a;
82     c.print();
83     c = c + b;
84     c.print();
85 
86     c = a + b;
87     c.print();
88     a.print();
89     return 0;
90 }

 

posted @ 2020-01-28 15:09  tnbryant  阅读(150)  评论(1)    收藏  举报