C++的类和对象(六):友元、内部类

目录

友元

友元函数

友元类

内部类

匿名对象

拷贝对象时的一些编译器优化

再次理解类和对象


友元

基本概念:友元提供了一种突破封装的方式,有时提供了便利,但是友元会增加耦合度,破坏了封装,所以友元不宜多用(开后门)

格式:friend 函数声明

分类:友元函数和友元类

友元函数

解决问题:类外无法访问成员函数

注意事项:

1、友元函数可以直接访问类的私有成员,它是定义在类外部的普通函数,不属于任何类,但需要在类的内部声明,声明时需要加friend关键字

class Date
{
     friend ostream& operator<<(ostream& _cout, const Date& d);
     friend istream& operator>>(istream& _cin, Date& d);
public:
     Date(int year = 1900, int month = 1, int day = 1)
     : _year(year)
     , _month(month)
     , _day(day)
     {}
private:
     int _year;
     int _month;
     int _day;
};

ostream& operator<<(ostream& _cout, const Date& d)
{
     _cout << d._year << "-" << d._month << "-" << d._day;
     return _cout; 
}

istream& operator>>(istream& _cin, Date& d)
{
     _cin >> d._year;
     _cin >> d._month;
     _cin >> d._day;
     return _cin;
}

int main()
{
     Date d;
     cin >> d;
     cout << d << endl;
     return 0;
}

2、友元函数可以访问类的私有和保护成员,但不是类的成员函数

3、友元函数不能用const修饰(没必要)

4、友元函数可以在类定义的任何地方声明,不受类的访问限定符限制

5、一个函数可以是多个类的友元函数

6、友元函数的调用与普通函数的调用原理相同

7、不想用友元就用get和set

友元类

注意事项:

1、友元的关系是单向的,不具有交换性(你是我的朋友我允许你看我,但不知道你让不我看你)

Time类中声明Date类是其友元类,则可以在Date类中访问Time类的私有成员变量,但想在Time类中访问Date类中私有的成员变量则不行:

class Time
{
   friend class Date;//声明日期类为时间类的友元类,则在日期类中就直接访问Time类中的私有成员变量

public:
     Time(int hour = 0, int minute = 0, int second = 0)
     : _hour(hour)
     , _minute(minute)
     , _second(second)
     {}
   
private:
     int _hour;
     int _minute;
     int _second;
};

class Date
{
public:
   Date(int year = 1900, int month = 1, int day = 1)
      : _year(year)
      , _month(month)
      , _day(day)
      {}
   
   void SetTimeOfDate(int hour, int minute, int second)
   {
       // 直接访问时间类私有的成员变量
       _t._hour = hour;
       _t._minute = minute;
       _t._second = second;
   }
   
private:
   int _year;
   int _month;
   int _day;
   Time _t;
};

2、友元关系不能传递(C是B的友元,B是A的友元,在未声明的情况下C不是A的友元)

3、友元关系不能继承

4、友元关系是双向时,两个类都可以访问对方的成员变量和成员函数

内部类

基本概念:一个类定义在另一个类的内部,这个内部类就叫内部类

注意事项:

1、类不占用空间(编译后不占用空间)

#include <iostream>
using namespace std;

class A
{
public:
	class B
	{
	private:
		int _b1;
	};
private:
	int _a1;
	int _a2;
};

int main()
{
	cout << sizeof(A)<<endl;
	return  0;
}

想象中在A类中嵌套一个B类应该是下的代码是这样的,但实际上不是:

2、内部类受外部类的类域的限制

3、内部类是外部类的友元(内部类可以访问外部类的成员,但是外部类不能访问内部类的成员)

4、内部类可以定义在外部类的任意位置

5、内部类可以直接访问外部类中的static成员,不需要外部类的对象或类名

#include <iostream>
using namespace std;

class A
{
private:
     static int k;
     int h;
public:
     class B // B天生就是A的友元
     {
     public:
         void foo(const A& a)
         {
         cout << k << endl;//OK,this->k
         cout << a.h << endl;//OK,this->h
         }
     };
};

int A::k = 1;

int main()
{
    A::B b;
    b.foo(A());
    return 0;
}
  • A() :匿名的临时对象
  • b.foo(A()): 将匿名对象作为参数传递给了类 A 中嵌套类 B 的成员函数 foo()

6、sizeof(外部类) = 外部类的大小,和内部类没有任何关系

匿名对象

格式:类名()

注意事项:

1、匿名对象的括号内可以有参数

2、匿名对象的声明周期只在当前一行(第1行定义匿名对象,第2行时该匿名对象销毁)

#include <iostream>
using namespace std;
class A
{
public:
    A(int a = 0)
        :_a(a)
    {
        cout << "A(int a)" << endl;
    }

    ~A()
    {
        cout << "~A()" << endl;
    }

private:
    int _a;
};

class Solution
{
public:
    int Sum_Solution(int n)
    {
        //...
        return n;
    }
};

int main()
{
    A aa1;//有名对象
  
    A();//匿名对象
    A(10);//匿名对象

    A aa2(2);//有名对象
    Solution().Sum_Solution(10);
    return 0;
}

3、匿名对象可以提供一些便利(当我们只是向调用对象的内容时有名写两行,匿名写一行)

//形式一
Solution s1;
s1.func(10);

//形式二
Solution().Sum_Solution(10);

拷贝对象时的一些编译器优化

基本概念:在传参和传返回值时,一般编译器会做一些优化,减少对象的拷贝

连续构造 + 拷贝构造 = 优化为直接构造

连续构造 + 拷贝构造 = 优化为一个构造

连续拷贝构造 + 拷贝构造 = 优化为一个拷贝构造

连续拷贝构造 + 赋值重载 = 无法优化

再次理解类和对象

        计算机不认识现实生活中的实体,只认识二进制格式的数据,如果想要计算机认识现实中的实体,用户必须通过某种面向对象的语言,对实体进行描述,然后通过编写程序,创建对象后计算机才可以认识,比如像要让计算机认识洗衣机就需要:

  1. 用户先对现实中的洗衣机实体进行抽象认知,即在思想层面对洗衣机进行认识,洗衣机有什么属性(成员变量)和功能(成员函数)
  2. 此时,人脑中已经对洗衣机有了一个较为清醒的认识,通过某种面相对象的语言将洗衣机用类来进行描述,就可以让计算机知道人脑中对洗衣机的认识
  3. 然后,在计算机中就有了一个洗衣机类,但它只是站在计算机的角度对洗衣机进行描述的,只有利用洗衣机类实例化出具体的洗衣机对象,用户才可以模拟现实中洗衣机实体的功能
#include <iostream>
#include <string>

class WashingMachine {
private:
    int capacity; // 洗衣容量
    bool isOn; // 洗衣机是否开启
    std::string brand; // 品牌

public:
    WashingMachine(int cap, const std::string& b) : capacity(cap), isOn(false), brand(b) {}

    void turnOn() {
        isOn = true;
        std::cout << "Washing machine turned on." << std::endl;
    }

    void turnOff() {
        isOn = false;
        std::cout << "Washing machine turned off." << std::endl;
    }

   void washClothes() {
       if(isOn) {
           std::cout << "Washing clothes..." << std::endl;
       } else {
           std::cout << "Please turn on the washing machine first."<<std:endl;;
       }
   }
};

int main() {
   WashingMachine myWasher(5, "ABC");
   
   myWasher.turnOn();
   myWasher.washClothes();
  
  return 0;

}

~over~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/452327.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

力扣--课程表--bfs+dfs

整体思路&#xff1a; 这是一道拓扑序列的题目&#xff0c;我们将边的方向定义成从先修课指向后修课的方向&#xff0c;借一下官方的题解图片&#xff0c;我们需要判断的是形成的这个图结构是否存在环&#xff0c;如果存在环&#xff0c;那么代表不能完成所有课程的学习。 bfs思…

2.Datax数据同步之Windows下,mysql和sqlserver之间的自定义sql文数据同步

目录 前言步骤操作大纲步骤明细mysql 至 sqlServersqlServer 至 mysql执行同步语句中报 前言 上一篇文章实现了不同的mysql数据库之间的数据同步&#xff0c;在此基础上本篇将实现mysql和sqlserver之间的自定义sql文数据同步 准备工作&#xff1a; JDK(1.8以上&#xff0c;推…

学习vue3第四节(ref以及ref相关api)

主要记录以下api&#xff1a;ref()、isRef()、unref()、 shallowRef()、triggerRef()、customRef() 1、ref() 定义 接受一个内部值&#xff0c;返回一个响应式的、可更改的 ref 对象&#xff0c;此对象只有一个指向其内部值的属性 .value&#xff0c;.value属性用于追踪并且存…

数据结构 第1章:绪论

文章目录 1. 绪论1.1. 数据结构 1.2. 算法1.2.1. 算法的基本概念1.2.2. 算法的时间复杂度1.2.3. 算法的空间复杂度 1. 绪论 程序 数据结构 算法 1.1. 数据结构 数据&#xff1a;是对客观事物的符号表示&#xff0c;在计算机科学中是指所有能输入到计算机中并被计算机程序处理…

记录一个Typora激活方法(附软件)!!!

前言 今天想体验Typora上的picList功能&#xff0c;手一抖给版本升级到最新的1.8.10&#xff0c;然后就提示我激活&#xff0c;让我输入序列号&#xff0c;如图所示。接着我就去百度找教程&#xff0c;于是乎就出现了这一篇文章。 教程开始 1、下载最新版 先去官网下载最新…

使用canvas绘制超炫时钟

HTML5 Canvas相当于一个画板&#xff0c;你可以在Canvas绘制任意的东西&#xff0c;今天要分享一款利用HTML5 Canvas绘制的超炫时钟的方法及代码&#xff0c;非常的漂亮&#xff0c;这里推荐给大家 代码地址 使用canvas绘制超炫时钟

R统计学2 - 数据分析入门问题21-40

往期R统计学文章&#xff1a; R统计学1 - 基础操作入门问题1-20 21. 如何对矩阵按行 (列) 作计算&#xff1f; 使用函数 apply() vec 1:20 # 转换为矩阵 mat matrix (vec , ncol4) # [,1] [,2] [,3] [,4] # [1,] 1 6 11 16 # [2,] 2 7 12 17 # [3,] …

Nodejs 第五十四章(net)

net模块是Node.js的核心模块之一&#xff0c;它提供了用于创建基于网络的应用程序的API。net模块主要用于创建TCP服务器和TCP客户端&#xff0c;以及处理网络通信。 TCP&#xff08;Transmission Control Protocol&#xff09;是一种面向连接的、可靠的传输协议&#xff0c;用于…

word中图片位置问题(后续遇到问题再更新)

问题1&#xff1a;图片插入后显示不全 具体表现为&#xff1a;复制黏贴、或者插入图片后&#xff0c;出现插入的图片显示不全&#xff0c;或者不显示。 例如&#xff1a; 这是因为&#xff1a;图片被设定了固定行距 解决方案&#xff1a;ctrl1 效果&#xff1a; 问题2&am…

2024蓝桥杯每日一题(二分)

一、第一题&#xff1a;教室 解题思路&#xff1a;二分差分 对天数进行二分&#xff0c;在ck函数中用差分方法优化多次区间累加。 【Python程序代码】 n,m map(int,input().split()) a [0] list(map(int,input().split())) d,s,t [0]*(m5),[0]*(m5),[0]*(m5) for…

Trust Region Policy Optimization (TRPO)

Trust Region Policy Optimization (TRPO) 是一种强化学习算法&#xff0c;专门设计来改善策略梯度方法在稳定性和效率方面的表现。由 John Schulman 等人在 2015 年提出&#xff0c;TRPO 的核心思想是在策略优化过程中引入一个信任区域&#xff08;trust region&#xff09;&a…

unity

Unity官方下载_Unity最新版_从Unity Hub下载安装 | Unity中国官网 Unity Remote - Unity 手册 登陆账号&#xff0c;找到一个3d 免费资源 3D Animations & Models | Unity Asset Store unity 里面window->package Manager 里面可以看到自己的asset &#xff0c;下载后…

【数据结构】顺序表的定义及实现方式

文章目录 顺序表的定义顺序表的实现静态分配动态分配动态申请内存空间&#xff0c;动态释放内存空间&#xff08;malloc&#xff0c;free&#xff09; 顺序表的特点总结 顺序表的定义 顺序表也就是用顺序存储的方式实现线性表。 顺序存储。把逻辑上相邻的元素存储在物理位置上…

kubernetes之概念入门篇

K8S的内容是要比docker多很多的。 kubernetes中文官网&#xff1a; Kubernetes(K8S)中文文档_Kubernetes中文社区 1、认识kubernetes 1.1、什么是kubernetes&#xff1f; kubernetes是一个开源的&#xff0c;用于管理云平台中多个主机上的容器化的应用&#xff0c;kubernetes…

漏洞发现-漏扫项目篇NucleiYakitGobyAfrogXrayAwvs联动中转被动

知识点 1、综合类-Burp&Xray&Awvs&Goby 2、特征类-Afrog&Yakit&Nuclei 3、联动类-主动扫描&被动扫描&中转扫描 章节点&#xff1a; 漏洞发现-Web&框架组件&中间件&APP&小程序&系统 扫描项目-综合漏扫&特征漏扫&被动…

探索TikTok云手机在社交媒体营销的作用

近年来&#xff0c;TikTok作为全球短视频平台之一&#xff0c;其用户基数呈现持续增长的趋势。伴随社交媒体的蓬勃发展&#xff0c;企业和个人纷纷涌入TikTok平台&#xff0c;追求更广泛的曝光和用户互动。为满足这一需求&#xff0c;TikTok云手机应运而生。本文将深度剖析TikT…

力扣面试经典150 —— 16-20题

力扣面试经典150题在 VScode 中安装 LeetCode 插件即可使用 VScode 刷题&#xff0c;安装 Debug LeetCode 插件可以免费 debug本文使用 python 语言解题&#xff0c;文中 “数组” 通常指 python 列表&#xff1b;文中 “指针” 通常指 python 列表索引 文章目录 16. [困难] 接…

nginx有几种启动方式

Nginx 通常可以以两种主要的方式启动&#xff1a;作为前台进程运行或作为守护进程&#xff08;后台&#xff09;运行。 前台运行&#xff1a; 当Nginx以前台模式运行时&#xff0c;它会在命令行保持活动状态&#xff0c;所有的日志输出都会直接显示在命令行上。这种模式通常用于…

execl/python读取数据库( Access、MySQL)

目录 一 、读取access数据库 &#xff08;一&#xff09;execl读取数据库 1.搜索ODBC&#xff08;注意自己的execl是64位还是32位&#xff09; 2.安装数据源的驱动程序 3.打开execl 4. 补充&#xff1a;选择数据源时&#xff0c;也可以直接在execl中选择数据源 &#xff…

丘一丘正则表达式

正则表达式(regular expression,regex,RE) 正则表达式是一种用来简洁表达一组字符串的表达式正则表达式是一种通用的字符串表达框架正则表达式是一种针对字符串表达“简洁”和“特征”思想的工具正则表达式可以用来判断某字符串的特征归属 正则表达式常用操作符 操作符说明实…