12.4 友元

PostgreSQL12.3——pgAdmin4表格的创建 概述 本文简要讲解一下pgAdmin4中如何用SQL语句创建表格。图形化创建的方式较为简单,不再赘述。使用的PostgreSQL的版本是12.3。 后序我也会继续更新关于PostgreSQL——pgAdmin4的其他使用方法,需要的盆友可关注啦! 主要步骤 第一步:创建一个数据库(这个网上的教程很多,而且也不容易出错,这里就不再赘述)。 第二步:建表 点击创建的数据库(myfirstdb)->Schemas->找到Tables右键->Query Tool 打开后应是如下界面: 在上述Q 阅读详情

目录

1.使用示例

        1.商品类

        2.促销类

2.友元的分类

3.作用域

        1.类

        2.全局函数

        3.成员函数


友元是一种机制,允许将类的非公有成员授权给外部类或函数访问。 友元通过friend关键字声明,只能出现在类定义内部。

1.使用示例

我们来举一个例子,假设我们有一个商品类Product,还有一个促销活动类Promotion。

1.商品类

商品类有3个数据成员,分别代表商品名称、所属类目、商品价格,正常情况下数据成员都是private的

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

class Product {
private:
    std::string productName;
    unsigned long categoryId;
    double price;
public:
    Product(std::string pname, unsigned long cid, double prc) : productName(pname), categoryId(cid), price(prc) {}
    Product() : categoryId(0), price(0) {}
};
2.促销类

促销活动类Promotion提供一个接口discount,根据商品所属的类目,判断商品是否参与促销,并计算促销后的价格。Promotion会大量访问Product的私有字段,但是这些私有字段又不希望被其他类/函数访问。可以将Promotion定义为Product的友元类

class Product {
friend class Promotion;  // 定义Promotion为友元类
private:
    std::string productName;
    unsigned long categoryId;
    double price;
public:
    Product(std::string pname, unsigned long cid, double prc) : productName(pname), categoryId(cid), price(prc) {}
    Product() : categoryId(0), price(0) {}
};

设置为友元类后,Promotion的成员函数就可以无障碍的访问Product的私有字段

class Promotion {
private:
    std::vector<unsigned long> categoryIds;
public:
    double discount(Product& p);
    Promotion(std::vector<unsigned long> &vec) : categoryIds(vec) {}
};

double Promotion::discount(Product& p) {
    std::vector<unsigned long>::iterator it = std::find(categoryIds.begin(), categoryIds.end(), p.categoryId);
    if (it == categoryIds.end()) { // 找不到,商品所属类目为参加促销
        return p.price;
    }
    else { // 参加促销
        return p.price * 0.9;
    }
}

下面是一段这两个类的测试代码

int main() {
    Product p1("Nike篮球鞋", 11UL, 9.8);
    Product p2("遮阳帽", 22UL, 6.6);

    std::vector<unsigned long> promotionCategoryIds;
    promotionCategoryIds.push_back(11UL);

    Promotion prom(promotionCategoryIds);

    std::cout << "p1.discount: " << prom.discount(p1) << std::endl; // 输出打9折的价格
    std::cout << "p2.discount: " << prom.discount(p2) << std::endl; // 输出不打折的价格
}
2.友元的分类

上面的例子中我们将Promotion类设置为Product的友元类,除了设置整个类为友元类。C++还支持将类的成员函数、全局函数设置为友元。设置的语法格式如下

class Product {
friend class Promotion;                           // 设置友元类
friend double discount(Product& p);               // 设置友元函数
friend double Promotion::discount(Product& p);    // 设置友元成员函数
private:
    std::string productName;
    unsigned long categoryId;
    double price;
public:
    Product(std::string pname, unsigned long cid, double prc) : productName(pname), categoryId(cid), price(prc) {}
    Product() : categoryId(0), price(0) {}
};
3.作用域
1.类

之前的示例中,Product类将Promotion类声明为自己的友元类,而此时Promotion类尚未定义。之所以能运行是因为friend class Promotion除了把Promotion声明为Product的友元类,还完成了Promotion类的声明,此时Promotion是已声明的不完全类型(incomplete type)。

2.全局函数

将全局函数声明为Product的友元函数时,同样可以先定义Product类,再定义函数,因为friend double discount(Product& p)同时完成了函数的声明。

class Product {
friend double discount(Product& p);
private:
    std::string productName;
    unsigned long categoryId;
    double price;
public:
    Product(std::string pname, unsigned long cid, double prc) : productName(pname), categoryId(cid), price(prc) {}
    Product() : categoryId(0), price(0) {}
};

double discount(Product& p) {
    return p.price;
}
3.成员函数

友元成员函数就不能先定义Product了,下面这段代码是编译不通过的,因为声明成员函数为友元的时候,Promotion并不存在。

class Product {
friend double Promotion::discount(Product& p);
private:
    std::string productName;
    unsigned long categoryId;
    double price;
public:
    Product(std::string pname, unsigned long cid, double prc) : productName(pname), categoryId(cid), price(prc) {}
    Product() : categoryId(0), price(0) {}
};

class Promotion {
private:
    std::vector<unsigned long> categoryIds;
public:
    double discount(Product& p);
    Promotion(std::vector<unsigned long>& vec) : categoryIds(vec) {}
};

只把Promotion的定义前移也不足以解决问题,因为Promotion::discount的定义依赖Product类型,这时候需要提前声明Product为不完全类型。完整流程如下

  1. 声明Product
  2. 定义Promotion类,因为Promotion依赖Product类,所以第1步必须要做
  3. 定义Product,将Promotion::discount定义为友元
  4. 定义Promotion::discount,因为discount会访问Product的数据成员,这一步必须在Product定义之后做
class Product;

class Promotion {
private:
    std::vector<unsigned long> categoryIds;
public:
    double discount(Product& p);
    Promotion(std::vector<unsigned long>& vec) : categoryIds(vec) {}
};

class Product {
friend double Promotion::discount(Product& p);
private:
    std::string productName;
    unsigned long categoryId;
    double price;
public:
    Product(std::string pname, unsigned long cid, double prc) : productName(pname), categoryId(cid), price(prc) {}
    Product() : categoryId(0), price(0) {}
};


double Promotion::discount(Product& p) {
    std::vector<unsigned long>::iterator it = std::find(categoryIds.begin(), categoryIds.end(), p.categoryId);
    if (it == categoryIds.end()) { // 找不到,商品所属类目为参加促销
        return p.price;
    }
    else { // 参加促销
        return p.price * 0.9;
    }
    return 0;
}

PYTHON 打印三角形大全 用PYTHON语言打印各种三角形 阅读详情

相关推荐

人形机器人解耦驱动腿部设计与FAST性能优化

机器人运动控制的核心在于动力学解耦与能量效率优化。通过多连杆机构设计,可以实现关节运动的独立控制,显著降低惯性叠加和能量损耗。DecARt Leg采用创新的齿轮-四杆复合机构,将腿部伸缩与摆动运动完全解耦,配合多杆踝关节传动系统,实测行走速度可达4.18m/s。这种解耦设计不仅提升了动态性能,其提出的FAST指标更为腿部构型提供了量化评估基准,在仓储物流、地形适应等场景展现出显著优势,为人形机器人运动控制提供了新的技术路径。

weixin_33759613的博客 239

C++ 12.5 友元

简介=================================================================================================== 在某些情况下,允许特定的非成员函数访问一个类的私有成员,同时任然阻止一般的访问。友元机制允许一个类将对其非公有成员的访问权授予指定的函数或类。 但是一个类将对其非公有成员的访问授予其他函数或类,会破

海螺上的斑点 615

Hive数据仓库分层架构实战:4层黄金模型×6大业务场景×万亿级数据优化方案

根据《2023数据中台成熟度报告》,‌78%的ETL任务性能瓶颈‌源于分层设计不合理。本文基于某头部电商平台PB级数据仓库建设经验,结合金融风控、用户画像、实时大屏等核心场景,深度解析‌ODS→DWD→DWS→ADS‌四层架构设计原则,揭秘‌万亿级数据治理方案‌与‌维度建模20大避坑策略‌。

优快云博客专家,领域包括但不限于:AI、大数据、Python、架构师,有合作、课程、问题、疑惑请私信博主 1484

C++ 友元

友元声明以关键字 friend 开始,它只能出现在类定义中。因为友元不是类授权的成员,所以它不受其所在类的声明区域 public private 和 protected 的影响。通常我们选择把所有友元声明组织在一起并放在类头之后。具体放的位置,要看团队的一致风格。

gopher9511的博客 741

OSMDroid 切换地图不更新的问题

用OSMDroid加载Google地图的时候 需要有按钮切换不同图层的地图,如果发现调用了mMapView.setTileSource(ITileSource aTileSource)方法的时候发现地图View没有更新的话,可能是因为两个实例化TileSource对象其子类BitmapTileSourceBase这个类的aName成员变量值一样导致的地图在setTileSource出现不更新问题,...

godoge的博客 1039

微带天线理论学习笔记(1)

微带天线的概念是由Deschamps于1953年提出来的,它是在一块厚度远小于工作波长的介质基片的一面敷以金属辐射片、一面全部敷以金属薄层作接地板而成。辐射片可以根据不同的要求设计成各种形状。微带天线具有质量轻、体积小和易于制造等优点,广泛应用于个人无线通信中。

qq_36521926的博客 6227

C++中的代码重用(七)=>模板友元

对于模板的友元一般分为三种: 1.非模板友元 2.约束模板函数 3.非约束模板函数 例子如下所示 //class_friend.h #ifndef CLASS_FRIEND_H #define CLASS_FRIEND_H /*非模板友元*/ #include&lt;iostream&gt; using namespace std; template&lt;typename U&gt;...

夏洛克福尔摩斯 302

CST软件中SPICE模型的高效导出与转换技巧(txt到cir实战指南)

本文详细介绍了在CST Studio Suite中高效导出与转换SPICE模型的实战技巧,重点讲解了如何将txt格式的模型转换为通用的cir格式。内容涵盖三种模型存在形式的处理方法、格式检查与内容清理、端口一致性验证等关键步骤,并提供了利用LTspice Export功能、批处理脚本以及结果一致性校验等进阶指南,帮助工程师实现场路协同仿真模型的无缝迁移与应用。

silver的专栏 1185

友元和静态

静态成员必须要在类外进行初始化,不能写在构造 函数中。因为静态成员只用初始化一次。在函数体内也不行,因为我们只声明了,并没有定义。改成这样才可以:将上述代码中的num定义成公有的可以.访问,直接访问,但是不可以::num访问。因为num是类域中的而不是全局域里面的。

2302_80090192的博客 928

使用STM32H7点亮RGB屏幕

希望本文能对你有所帮助!RGB屏幕是一种具有红、绿、蓝三种颜色通道的显示设备,通过控制每个通道的亮度,可以显示出丰富多彩的图像和动画。要使用STM32H7控制RGB屏幕,我们需要连接适当的引脚,并编写适当的代码来控制每个颜色通道的亮度。在主循环中,我们先点亮红色通道,然后延迟一段时间,接着点亮绿色通道,再延迟一段时间,最后点亮蓝色通道,并再次延迟。需要注意的是,示例代码中的延迟循环使用了一个简单的计数器实现,但实际应用中可能需要更精确的延迟方式,例如使用定时器中断或操作系统提供的延迟函数。

QoyOle的博客 925

1、微软 Intune 全面指南:配置、管理与自动化

本文全面介绍了微软 Intune 的配置、管理和自动化操作,涵盖用户与设备管理、安全策略设置、跨平台应用部署、合规性监控及报告分析等内容。通过详细的操作步骤、自动化脚本示例和流程优化建议,帮助技术人员高效掌握 Intune 在混合办公环境中的实际应用,并展望其未来发展趋势。

ii567的博客 361

5.6 友元

友元是为了提高程序效率而引入的,它允许非成员函数或类访问类的私有成员。友元函数和友元类在定义和使用上与普通函数和类没有太大区别,但它们破坏了类的封装性和隐藏性。友元应谨慎使用,避免滥用以保证代码的安全性和可维护性。

tang7mj的博客 1062

linux v3h平台开发系列详解(GMSL摄像头篇):1.11 解串器MIPI 1.5G高速率特殊deskew配置

解串器max96712 deskew配置

xian18809311584的博客 1776

c++友元

其实它这个设计者从生活中得到的设计灵感吧。 比如说你们家,有客厅和卧室两个地方。对于客厅是所有的客人都可以访问的。 但是你们家的卧室就是比较私密的地方,不是所有的客人都可访问 但是,可能你的好闺蜜,好朋友,跟你关系很好,你是允许他们访问你们家的卧室的 程序中也有类似的友元关系 友元的目的就是为了,让类或者函数访问某个类的私有成员 友元关键字为 friend 友元的三种实现 ...

weixin_30667649的博客 152

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

05 友元

友元 概念 友元可以访问与其有好友关系的类中的成员。 友元提供不同类的成员函数之间、类的成员函数与一般函数之间进行数据共享的机制。 实际是对封装的破坏 友元既可以是不属于任何类的一般函数,也可以是另一个类的成员函数,还可以是整个的类。 包括: 友元函数 不是当前类的成员函数,而是独立于当前类的外部函数 可以访问该类的所有对象的成员,包括私有、保护、公有成员 声明: 位置:类体中 格式:函数名前加friend 定义: 类体内:函数名前加friend Example 1. 在

weixin_50755913的博客 434

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

2.7、C++友元的使用

2.7、C++友元的使用 友元有友元函数和友元类。 友元的存在是为了可以不通过调用成员函数就可以直接访问类的私有数据,以提高程序运行效率。 友元其实是破坏了类的封装性。 友元的关键字:friend。 2.7.1、友元函数 在类体内说明,在函数的类型说明符前加关键字friend; 在类体外定义,定义格式与普通函数相同; 友元函数不是成员函数; 友元函数可以直接访问类体内的私有成...

qq_43755653的博客 274

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

04 c++中的友元

c++中的类具有封装性,类中的私有数据只有该类的成员函数可以访问,程序中访问类中的私有成员,必须通过对象来调用成员函数,但是频繁的调用会使运行效率降低。 为了解决上述问题,c++中加入友元机制,友元可以不通过调用成员函数直接访问类的私有数据来提高运行效率。 友元可以是函数(友元函数)也可以是类(友元类) 友元函数: 类体内说明,加friend关键字,在类体外定义,定义格式和普...

weixin_30478619的博客 153

C++——友元

写在前面 类具有封装性,类中的私有数据只有通过该类的成员函数才可以访问。如果在程序中需要访问类的私有成员,就必须通过对象来调用类的成员函数,但是频繁调用成员函数将影响程序运行效率。为解决上述问题,C++提供一种友元机制,友元可以不通过调用成员函数就可以直接访问类的私有数据,以提高程序运行效率。 友元机制在数据封装这堵不透明的墙上开了一个小孔,方便了类外对象进行数据的访问,但是它破坏了封装性,因此友元的使用也要慎重。友元可以是一个普通函数,可以是一个类的成员函数,也可以是一个类。 友元函数 普通函数声明为友元

weixin_50464560的博客 509

C++中的友元机制

■□□1.友元机制允许一个类将其非公有成员的访问权授予指定的函数或类。2.友元的声明可出现在类中的任何地方,友元不是类的成员,所以它不受其声明部分的访问控制的影响。3.通常将友元的声明成组的放在类的开始或结尾处是一个好主意。4.友元可以是普通的非成员函数,可以是其它类的成员函数,也可以是整个类。当我们将成员函数声明为友元时,函数名必须用该函数所属的类名限定。5.一般的讲,必须先定义包含成员函数的类

CARL_SEN的专栏 1116

C++——友元、异常和其他

一、友元   类并非只能拥有友元函数,也可以将类作为友元。在这种情况下,友元类的所有方法都可以访问原始类的私有成员和保护成员。另外,也可以做更严格的限制,只将特定的成员函数指定为另一个类的友元。哪些函数、成员函数或类为友元是由类定义的,而不能从外部强加友情。因此,尽管友元被授予从外部访问类的私有部分的权限,但它们并不与面向对象的编程思想相违背;相反,它们提高了公有接口的灵活性。   1、友元类...

weixin_30500473的博客 284

C++中的友元

1,友元的超能力在初始的时候能力很好、很实用,但是随着软件工程的发展,大家 越来越觉得友元的超能力是那么的不够友好,于是在实际的开发中,友元的超 能力就被遗弃了; 2,友元的概念: 1,友元是 C++ 中的一种关系; 1,这种关系发生在两个实体之间; 2,友元关系发生在函数与类之间或者类与类之间; 3,友元关系时单向的,不能传...

weixin_30374009的博客 101

降AI工具4.8元vs8元vs12元:贵的真的更好吗?

降AI工具价格从2元到12元一千字不等,贵的效果就好吗?实测4个价位的降AI工具,发现4.8元档的嘎嘎降AI性价比碾压高价工具。

why_not_do_som的博客 108

C++ 友元类使用 (friend)

C++中私有变量对外部类是不能直接访问的,也是不能继承的。 使用友元类可以访问类中的私有方法、私有变量,虽然对类的封装有一定的破坏,但是有时也是很实用的。 在实际中,在修改已有代码时,为了不大改动已有代码: (1) 对于没有继承关系的类,如果有关联,使用友元类还是比较方便的。 (2) 对于有继承关系的类,如果有关联,可以将变量访问由private改为protected。   直接看代码...

weixin_34021089的博客 275

C++一分钟之-属性友元与访问控制

在C++中,类的封装性是其核心特性之一,它允许我们定义数据成员和成员函数,并通过访问修饰符(public,protected,private)来控制它们的可访问性。然而,在某些情况下,我们可能希望让一个非成员函数或另一个类能够访问当前类的私有或保护成员,这时就需要用到“友元”(friend)的概念。什么是友元?友元函数...

weixin_41513148的博客 112

matlab元胞元素_12 Matlab 元胞数组

什么是元胞数组前面咱们介绍过矩阵的概念,但是矩阵有一个缺陷,它只能存储同一种类型的数据。同一个矩阵中,要么都是数字,要么就都是字符串。元胞数组 ( Cell Array ) 就可以解决这个问题。这里插播一个问题:一会儿说矩阵一会儿又说数组的,这两个是一回事吗?严格意义上,数组比矩阵的概念外延更大一些。矩阵单纯由数字元素构成,而数组不仅可以是数字元素,也可以是字符元素。在前面,我已经混着用了,所以,...

weixin_39989796的博客 966
上一篇: 12.3 构造函数
下一篇: 13.1 复制控制
randy.lou
博客等级 码龄15年 853粉丝 77原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值