第四层:友元与函数成员别样定义

简介: 第四层:友元与函数成员别样定义

前情回顾


上回到,在进入第三层后,我学习了隐藏在编译器内的一种神秘力量——this指针,this指针可以让编译器分清是哪个对象在调用类内的成员函数,同时,随着层数的增高,我对C++的理解越来越深,也越来越发觉C++的恐怖…


🚄上章地址:第三层:C++对象模型和this指针


友元


“上到这里来,你也是一个有缘人了,老夫看你有大机缘在身,这层内容不难,友元,有缘人祝你好运,哈哈哈哈哈…”这道声音在我踏入到第四层的那一刻响起,“有缘,友元吗?”我小声嘀咕着,看向了面前的石碑上。


友元的概念


在生活中,每个人都有一些可以让大众知道并且访问的,比如名字,也有一些是不想让大众访问的,比如手机、汽车这些私密物品,但是如果经过本人同意,该人的好朋友就可以对私密物品进行访问,同样,在C++中,也有私有属性(private),可以让类外一些特殊的函数或者类进行访问,而这些特殊的函数或者类就需要用到友元。


友元的目的


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


友元的关键字


友元的关键字是friend,也就是中文的朋友。


友元的两种种用法


1.全局函数做友元


2.类做友元


全局函数做友元


当程序员想让全局函数访问一个类内的私有属性时,只需要将函数声明在类内的最上方,并且在函数发返回类型之前加上友元的关键字friend:


#include<string>
#include<iostream>
using namespace std;
class person
{
  friend void test1();
public:
  person()
  {
  _name = "张三";
  _car = "奥迪A8";
  _phone = "iphone 100 por max";
  }
  string _name;
private:
  string _car;
  string _phone;
};
void test1()
{
  person p1;
  cout << "现在在访问:" << p1._name << endl;
  cout << "现在在访问:" << p1._name << "的" << p1._car << endl;
  cout << "现在在访问:" << p1._name << "的" << p1._phone << endl;
}
int main()
{
  test1();
  return 0;
}

0a2653c851af460fa595bd959398a8f1.png

那这里可能会有人有疑问,是不是直接在类内声明就可以,不加前面friend是不是也可以访问?实验一下:


#include<string>
#include<iostream>
using namespace std;
class person
{
  void test1();
public:
  person()
  {
  _name = "张三";
  _car = "奥迪A8";
  _phone = "iphone 100 por max";
  }
  string _name;
private:
  string _car;
  string _phone;
};
void test1()
{
  person p1;
  cout << "现在在访问:" << p1._name << endl;
  cout << "现在在访问:" << p1._name << "的" << p1._car << endl;
  cout << "现在在访问:" << p1._name << "的" << p1._phone << endl;
}
int main()
{
  test1();
  return 0;
}

0eacb84100b54626af849e6b562bf92a.png


可以看到报错是不可访问,所以证明,不仅仅需要在类内声明函数还需要加上关键字friend。


类做友元


类做友元,通过表面意思得知,是让一个类做另一个类的友元,然后可以用友元这个类访问把它当作友元的这个类,要注意的来了:


1.要访问的话,需要让当作友元这个类成为友元类内的一个对象成员,这个对象成员

好是个指针,在创建对象时,利用new操作符申请一块对象成员大小的空间让指针指向

2.注意,因为使用了new操作符,在程序快要结束的时候,记得使用delete释放空间,并且对指针进行置空,以免造成野指针

#include<string>
#include<iostream>
using namespace std;
class person1;
class person
{
  friend class person1;
public:
  person()
  {
  _name = "张三";
  _car = "奥迪A8";
  _phone = "iphone 100 por max";
  }
  string _name;
private:
  string _car;
  string _phone;
};
class person1
{
public:
  void test()
  {
  cout << "现在访问的是:" << p->_name<< endl;
  cout << "现在访问的是:" << p->_name<< "的" <<  p->_car<< endl;;
  cout << "现在访问的是:" << p->_name << "的" << p->_phone << endl;;
  }
  person *p;
};
void test1()
{
  person1 pp1;
  pp1.p = new person;
  pp1.test();
  delete pp1.p;
  pp1.p = NULL;
}
int main()
{
  test1();
  return 0;
}

0a2653c851af460fa595bd959398a8f1.png


函数成员的别样定义


函数成员其实也可以在类外进行定义,是什么意思呢?其实就是将函数成员在类内进行声明,在类外进行定义,定义时同样要让编译器知道是类内成员,所以也要在函数名前加类名::类外声明写法是


返回值 类名::函数名 ();

当时构造函数时

类名::类名 ();


可以进行验证:


#include<string>
#include<iostream>
using namespace std;
//class person1;
//
class person
{
public:
  person();
  void test1();
  string _name;
  string _car;
  string _phone;
};
person::person()
{
  _name = "张三";
  _car = "奥迪A8";
  _phone = "iphone 100 por max";
}
void person::test1()
{
  cout << "现在访问的是:" << _name << endl;
  cout << "现在访问的是:" << _name << "的" << _car << endl;
  cout << "现在访问的是:" << _name << "的" << _phone << endl;
}
int main()
{
  person p1;
  p1.test1();
  return 0;
}

0a2653c851af460fa595bd959398a8f1.png

可以看到时正常运行的。


有缘人学友元,急速突破第四层


巨大石碑轰然倒塌,一阵烟土飘起,散去之后,只见一个身影向第五层走去…


本章知识点(图片形式)


0eacb84100b54626af849e6b562bf92a.png


😘预知后事如何,关注新专栏,和我一起征服C++这座巨塔

🚀专栏:C++爬塔日记

🙉都看到这里了,留下你们的👍点赞+⭐收藏+📋评论吧🙉


相关文章
|
5月前
|
编译器 C++
C++类与对象(四):再谈构造函数(详解初始化列表)、Static成员
C++类与对象(四):再谈构造函数(详解初始化列表)、Static成员
90 0
|
5月前
|
存储 Serverless 数据安全/隐私保护
C++ 类的成员函数和数据成员的技术性探讨
C++ 类的成员函数和数据成员的技术性探讨
53 0
|
4月前
类与对象\常成员
类与对象\常成员
17 1
|
5月前
|
C++
【C++成长记】C++入门 | 类和对象(下) |Static成员、 友元
【C++成长记】C++入门 | 类和对象(下) |Static成员、 友元
|
5月前
|
编译器 C++
【C++练级之路】【Lv.4】类和对象(下)(初始化列表,友元,static成员,编译器的优化)
【C++练级之路】【Lv.4】类和对象(下)(初始化列表,友元,static成员,编译器的优化)
|
5月前
|
存储 编译器 C语言
【C++练级之路】【Lv.2】类和对象(上)(类的定义,访问限定符,类的作用域,类的实例化,类的对象大小,this指针)
【C++练级之路】【Lv.2】类和对象(上)(类的定义,访问限定符,类的作用域,类的实例化,类的对象大小,this指针)
【C++系列P5】‘类与对象‘-三部曲——[对象&特殊成员](3/3)
【C++系列P5】‘类与对象‘-三部曲——[对象&特殊成员](3/3)
|
Java 编译器 C++
类与对象(三):stactic成员、友元、内部类
在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值。
46 0
|
编译器 C++
【C++】类和对象(下)—— 再谈构造函数 | static成员 | C++11补丁 |友元(上)
【C++】类和对象(下)—— 再谈构造函数 | static成员 | C++11补丁 |友元(上)
151 0
【C++】类和对象(下)—— 再谈构造函数 | static成员 | C++11补丁 |友元(上)
|
Java 编译器 C++
【C++】类和对象(下)—— 再谈构造函数 | static成员 | C++11补丁 |友元【C++】类和对象(下)—— 再谈构造函数 | static成员 | C++11补丁 |友元(下)
【C++】类和对象(下)—— 再谈构造函数 | static成员 | C++11补丁 |友元【C++】类和对象(下)—— 再谈构造函数 | static成员 | C++11补丁 |友元(下)
175 0
【C++】类和对象(下)—— 再谈构造函数 | static成员 | C++11补丁 |友元【C++】类和对象(下)—— 再谈构造函数 | static成员 | C++11补丁 |友元(下)