C++中成员函数和友元函数的使用及区别详解

为什么使用成员函数和友元函数

这个问题至关重要,直接影响着后面的理解:

程序数据: 数据是程序的信息,会受到程序函数的影响。封装是面向对象编程中的把数据和操作数据的函数绑定在一起的一个概念,这样能避免受到外界的干扰和误用,从而确保了安全。

数据封装引申出了另一个重要的 OOP 概念,即 数据隐藏 。数据封装 是一种把数据和操作数据的函数捆绑在一起的机制, 数据抽象 是一种仅向用户暴露接口而把具体的实现细节隐藏起来的机制。C++ 通过创建类来支持封装和数据隐藏(public、protected、private)。我们已经知道,类包含私有成员(private)、保护成员(protected)和公有成员(public)成员。默认情况下,在类中定义的所有项目都是私有的。
由于C++的封装和隐藏特性,只有类定义的成员函数可以访问类定义的私有数据。

成员函数是数据封装和数据隐藏的机制。

友元是C++提供的一种破坏数据封装和数据隐藏的机制。

成员函数的使用

首先先看代码

class Stock{ //class declaration
private:
    std:: string company;
    long shares;
    double share_val;
    double total_val;
void set_tot(){ total_val=shares* share_val;}
public:
void acquire(const std:: string & co, long n, double pr);
void buy(long num, double price);
void se11(long num, double price);
void update(double price);
void show();
};//note semicolon at the end

注意这里面的private可以不写,如果不写的话默认是私有的。
其中,company、shares等都是Stock类的私有数据成员。如果试图使用非成员函数访问这些数据成员编译器禁止这样做。如果试图破解该机制,友元是另一种选择。

实现类成员函数
(1)定义成员函数时,使用作用域解析运算符(::)来标识函数所属的类;

void Stock::update(double price)

(2)类方法可以访问类的private组件。

友元

C++是从结构化的C语言发展而来的,需要照顾结构化设计程序员的习惯,所以在对私有成员可访问范围的问题上不可限制太死。
C++设计者认为,如果有的程序员真的非常怕麻烦,就是想在类的成员函数外部直接访问对象的私有成员,那还是做一点妥协以满足他们的愿望为好,这也算是眼前利益和长远利益的折中。因此,C++就有了友元(friend)的概念。打个比方,这相当于是说:朋友是值得信任的,所以可以对他们公开一些自己的隐私。
友元提供了一种普通函数或者类成员函数访问另一个类中的私有或保护成员的机制。也就是说有两种形式的友元:
(1)友元函数:普通函数对一个访问某个类中的私有或保护成员。
(2)友元类:类A中的成员函数访问类B中的私有或保护成员。
(3)友元成员函数

友元函数
创建友元函数的第一步是将其原型放在类声明中,并在原型声明前加上关键字friend:

friend Time operator*(double m,constTime&t);

注意该声明可以在类外也可以在类中
这样即使operator不是成员函数 ,但它与成员函数的访问权限相同,可以访问类中的私有变量。

友元类
类Y的所有成员函数都为类X友元函数

class girl;
class girl{
private:
  char *name;
  int age;
  friend boy; //声明类boy是类girl的友元
};
class boy{
public:
  void disp(girl &);
};
void boy::disp(girl &x) //函数disp()为类boy的成员函数,也是类girl的友元函数
{
    //借助友元,在boy的成员函数disp中,借助girl的对象,直接访问girl的私有变量
   cout<<"girl's name is:"<<x.name<<",age:"<<x.age<<endl;
}

成员函数作友元
类Y的一个成员函数为类X的友元函数
目的:使类Y的一个成员函数成为类X的友元,具体而言:在类Y的这个成员函数中,借助参数X,可以直接使用X的私有变量
语法:声明在公有中 (本身为函数)
声明:friend + 成员函数的声明
调用:先定义Y的对象y—使用y调用自己的成员函数—自己的成员函数中使用了友元机制

class Stock{ //class declaration
private:
    std:: string company;
    long shares;
    double share_val;
    double total_val;
void set_tot(){ total_val=shares* share_val;}
public:
void acquire(const std:: string & co, long n, double pr);
void buy(long num, double price);
void se11(long num, double price);
void update(double price);
void show();
};
class Market{
    friend void Stock::acquire(const std:: string & co, long n, double pr);
    //Stock类下的acquire可以作为该成员函数的友元函数,可以访问该类的私有变量
    int price;
    int fiture;
public:
    void stuff();
};

如代码所示,Stock类下的acquire函数作为Market的友元函数可以访问market类的私有变量。

友元函数和类的成员函数的区别

友元函数和类的成员函数的区别成员函数有this指针,而友元函数没有this指针。友元函数是不能被继承的,就像父亲的朋友未必是儿子的朋友。

总结

到此这篇关于C++中成员函数和友元函数的使用及区别详解的文章就介绍到这了,更多相关C++成员函数和友元函数内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C++运算符重载 成员函数与友元函数详解

    复制代码 代码如下: #include<iostream>using namespace std;class A{    int x,y;    public:    A(int xx,int yy):x(xx),y(yy){}    A(){x=0;y=0;}    A operator+(const A&b) //不加const限定,也可以    { return A(x+b.x,y+b.y); }    A operator-()    { return A(-x,-y); } 

  • java 中同步、异步、阻塞和非阻塞区别详解

    java 中同步.异步.阻塞和非阻塞区别详解 简单点说: 阻塞就是干不完不准回来,一直处于等待中,直到事情处理完成才返回: 非阻塞就是你先干,我先看看有其他事没有,一发现事情被卡住,马上报告领导. 我们拿最常用的send和recv两个函数来说吧... 比如你调用send函数发送一定的Byte,在系统内部send做的工作其实只是把数据传输(Copy)到TCP/IP协议栈的输出缓冲区,它执行成功并不代表数据已经成功的发送出去了,如果TCP/IP协议栈没有足够的可用缓冲区来保存你Copy过来的数据的话

  • 基于php中echo用逗号和用点号的区别详解

    实例如下: <?php //点和逗号的测试,涉及到字符串的强制转换 echo 1+5; echo "<br /><br />"; echo '1+5='."1+5"."<br />"; echo '1+5='."5+1","<br /><br />"; echo '1+5=',1,"<br />"; //用逗号

  • 浅谈java中集合的由来,以及集合和数组的区别详解

    对象多了用集合存,数据多了用数组存. 数组是固定长度的,集合是可变长度的. 集合是:只要是对象就可以存,不管是不是同一种对象 而数组只能存储一种类型的对象 下面是集合的框架: 以上就是小编为大家带来的浅谈java中集合的由来,以及集合和数组的区别详解的全部内容了,希望对大家有所帮助,多多支持我们~

  • C++中静态存储区与栈以及堆的区别详解

    学习c++如果不了解内存分配是一件非常可悲的事情.而且,可以这样讲,一个C++程序员无法掌握内存.无法了解内存,是不能够成为一个合格的C++程序员的.一.内存基本构成可编程内存在基本上分为这样的几大部分:静态存储区.堆区和栈区.他们的功能不同,对他们使用方式也就不同.静态存储区:内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.它主要存放静态数据.全局数据和常量.栈区:在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放.栈内存分配运算

  • jsp中include指令静态导入和动态导入的区别详解

    1.什么是静态导入? 静态导入指的是,将一个外部文件嵌入到当前JSP文件中,同时解析这个页面的JSP语句,它会把目标页面的其他编译指令也包含进来.include的静态导入指令使用语法: 复制代码 代码如下: <%@include file="relativeURLSpec"%> 静态导入使用范例include1.jsp: 复制代码 代码如下: <%@ page contentType="text/html; charset=utf-8" langu

  • Python中表达式x += y和x = x+y 的区别详解

    前言 本文主要给大家介绍的是关于Python中表达式x += y和x = x+y 区别的相关内容,分享出来供大家参考学习,下面来看看详细的介绍: 直接看下面代码: x +=y In [66]: id(a) Out[66]: 4476839480 In [67]: id(b) Out[67]: 4476839480 In [68]: a = [1, 2, 3] In [69]: b = a In [70]: id(a) Out[70]: 4477149984 In [71]: id(b) Out[

  • MySQL中B树索引和B+树索引的区别详解

    目录 1.多路搜索树 2.B树-多路平衡搜索树 3.B树索引 4.B+树索引 总结 如果用树作为索引的数据结构,每查找一次数据就会从磁盘中读取树的一个节点,也就是一页,而二叉树的每个节点只存储一条数据,并不能填满一页的存储空间,那多余的存储空间岂不是要浪费了?为了解决二叉平衡搜索树的这个弊端,我们应该寻找一种单个节点可以存储更多数据的数据结构,也就是多路搜索树. 1. 多路搜索树 1.完全二叉树高度:O(log2N),其中2为对数,树每层的节点数: 2.完全M路搜索树的高度:O(logmN),其

  • C++中成员函数和友元函数的使用及区别详解

    为什么使用成员函数和友元函数 这个问题至关重要,直接影响着后面的理解: 程序数据: 数据是程序的信息,会受到程序函数的影响.封装是面向对象编程中的把数据和操作数据的函数绑定在一起的一个概念,这样能避免受到外界的干扰和误用,从而确保了安全. 数据封装引申出了另一个重要的 OOP 概念,即 数据隐藏 .数据封装 是一种把数据和操作数据的函数捆绑在一起的机制, 数据抽象 是一种仅向用户暴露接口而把具体的实现细节隐藏起来的机制.C++ 通过创建类来支持封装和数据隐藏(public.protected.p

  • C++中友元类和嵌套类使用详解

    目录 前言 1. 友元类 2. 友元成员函数 3. 其他友元关系 3.1 成为彼此的友元类 3.2 共同的友元 4. 嵌套类 嵌套类的作用域和访问控制 作用域 前言 友元这个词,在学习类的时候肯定接触过,但是当时我们只用了很多友元函数. 友元有三种: 友元函数 友元类 友元类方法 类并非只能拥有友元函数,也可以将类作为友元.在这种情况下,友元类的所以方法都能访问原始类的私有成员和保护成员.另外,也可以做更严格的限制,只将特定的成员函数指定为另一个类的友元. 1. 友元类 假如我们有两个类:Tv电

  • Python函数进阶之迭代器的原理与使用详解

    目录 什么是迭代器 概念 特征 惰性序列 检查可迭代对象 定义迭代器 使用iter函数 使用__iter__方法 判断迭代器 检查内置方法 使用collections模块 调用迭代器 使用next方法和函数 什么是迭代器 能被 next 指针调用,并不断返回下一个值的对象,叫做迭代器.表示为Iterator,迭代器是一个对象类型数据. 概念 迭代器指的是迭代取值的工具,迭代是一个重复的过程,每次重复都是基于上一次的结果而继续的,单纯的重复并不是迭代. 特征 迭代器并不依赖索引,而通过 next

随机推荐