zoukankan      html  css  js  c++  java
  • C++友元函数、友元类

    1、什么是友元函数?

    友元函数就是可以直接访问类的成员(包括私有数据)的非成员函数,也就是说他并不属于这个类,他是一种外部的函数。

    一个外部函数只能通过类的授权成为这个类友元函数,这就涉及到一个关键字friend。因为我们的一个外部函数是无法访问一个类的私有数据的,当然可以访问

    public修饰的变量,这就不叫私有数据了。

    1、友元全局函数

    (1)首先说明友元全局函数首先他是一个普通的全局函数,其次他是一个的类的友元函数,也就是意味着我们可以通过友元函数

    访问类的私有数据和成员函数,当然首先这个友元函数的参数是一个这个类的引用、类的指针或者就是这个类对象。

    (2)声明全局友元函数如下所示:

     1 #include <iostream>
     2 using namespace std;
     3 
     4 class Time{
     5     friend void func(Time &t);   // 声明全局函数为一个友元函数
     6 public:
     7     Time(int h, int m, int s) : i_mHour(h), i_mMin(m), i_mSecon(s) { }                  // 构造函数
     8 private:
     9     int i_mHour;
    10     int i_mMin;
    11     int i_mSecon;
    12 };
    13 
    14 static void func(Time &t)    // 全局函数
    15 {
    16     cout << t.i_mHour << ":" << t.i_mMin << ":" << t.i_mSecon << endl;
    17 }
    18 
    19 int main(void)
    20 {
    21     Time t = {10, 20, 30};
    22     func(t);
    23     return 0;
    24 }
    全局友元函数

    2、友元成员函数

    (1)首先说明友元成员函数是一个类的成员函数,其次他是另一个类的友元函数,所以我们也可以在这个函数中访问这个类的私有数据和成员函数

    (2)声明友元成员函数如下所示:

     1 #include <iostream>
     2 using namespace std;
     3 
     4 class Time;
     5 
     6 class Print{
     7 public:
     8     void func(Time &t);   // func函数是Time类的友元函数
     9 };
    10 
    11 class Time{
    12     friend void Print::func(Time &t);  // 声明Print类中的func函数是Time类的友元函数
    13 public:
    14     Time(int x, int y, int z) : i_mHour(x), i_mMin(y), i_mSecon(z) { }
    15 private:
    16     int i_mHour;
    17     int i_mMin;
    18     int i_mSecon;
    19 };
    20 
    21 void Print::func(Time &t)
    22 {
    23     cout << t.i_mHour << ":" << t.i_mMin << ":" << t.i_mSecon << endl;  // 直接操作Time中的私有数据
    24 }
    25 
    26 int main(void)
    27 {
    28     Time t(10,20,30);
    29     Print p;
    30     p.func(t);
    31     return 0;
    32 }
    友元成员函数

    3、友元类

    (1)友元类就是在A类中将B类声明为A类的友元类,方法就是:friend 类名

    (2)代码如下:

     1 #include <iostream>
     2 using namespace std;
     3 
     4 class Print;
     5 
     6 class Time{
     7     friend Print;         // 声明Print类为Time类的友元类
     8 public:
     9     Time(int x, int y, int z) : i_mHour(x), i_mMin(y), i_mSecon(z) { } // 构造函数
    10 private:
    11     int i_mHour;
    12     int i_mMin;
    13     int i_mSecon;
    14 };
    15 
    16 class Print{
    17 public:
    18     Print(int x, int y, int z) : t(x, y, z) {  }  // 构造函数
    19     void func(void);             // 可以在这个函数中去操作Time对象t的私有数据 
    20 private:
    21     Time t;           // 申明一个Time类对象
    22 };
    23 
    24 void Print::func(void)
    25 {
    26     cout << t.i_mHour << ":" << t.i_mMin << ":" << t.i_mSecon << endl;  // 直接操作Time中的私有数据
    27 }
    28 
    29 int main(void)
    30 {
    31     Print p(10,20,30);       // 定义一个Print类对象
    32     p.func();                
    33     return 0;
    34 }
    友元类

    3、注意一些问题

    (1)在类中声明的友元函数或者是友元类与类限定符没有任何关系,因为友元函数并不属于这个类,所以类的修饰限定符并不能对他起作用

     1 class Time{
     2     friend void func1(Time &t);  // 一般申明在类的开头位置处
     3     ......
     4 public:
     5     friend void func2(Time &t);  // 申明在public下
     6     ......
     7 private: 
     8     friend void func3(Time &t);  // 申明在private下
     9     ......
    10 protected:
    11     friend void func4(Time &t);  // 申明在protected下
    12     ......
    13 };
    友元与限定符

    (2)成员函数有this指针,而友元函数没有this指针。

    (3)友元函数是不能被继承的,就像父亲的朋友未必是儿子的朋友,这个其实很好理解,也很合理。

    (4)友元关系的单向性

    A是B的友元,B不是A的友元

    (5)友元声明的形式及数量不受限制

    我们可以声明多个类的友元函数或者友元类,而且函数可以是一个运算符重载函数,也可以是其他的什么函数。

    (6)友元只是封装的补充,其实是破坏了类的封装特性,所以我们如果能够不是用的情况尽量不要去使用。

  • 相关阅读:
    <<< List<HashMap<String, Object>> 及 HashMap<String, Object> 的用法
    <<< html图片背景平铺
    <<< javascript地址栏,代码
    Linux下常用目录有哪些?分别有什么作用?
    【Linux】Linux下进程间的通信方式
    【Linux】守护进程的定义,作用,创建流程
    【Linux】进程的结构,创建,结束,以及程序转化为的进程的过程
    【Linux】僵尸进程,孤儿进程以及wait函数,waitpid函数(有样例,分析很详细)
    【Linux】多线程同步的四种方式
    【Linux】多线程入门详解
  • 原文地址:https://www.cnblogs.com/deng-tao/p/6011796.html
Copyright © 2011-2022 走看看