当前位置: 首页 > news >正文

C++高频知识点(二十一)

文章目录

  • 101. 谈谈你对友元函数的认识
    • 1. 友元函数的定义和使用
    • 2. 友元函数的特性
    • 3. 友元函数的用途
      • 举个例子:操作符重载
    • 4. 友元函数的缺点和注意事项
  • 102. 什么是观察者模式?
    • 实现一个观察者模型
    • 与发布订阅模式的区别
  • 103. 虚函数说一下,虚函数和纯虚函数的区别?
  • 104. 说说map和unordered_map的区别,实现方式
    • 1. map 与 unordered_map 的区别
    • 2. map 的实现方式:红黑树
    • 3. unordered_map 的实现方式:哈希表
    • 4. 使用示例
      • 使用 map
      • 使用 unordered_map
    • set 和 map 的区别
  • 105. HTTPS加密方式
    • 证书和颁发验证的过程示意图

101. 谈谈你对友元函数的认识

在这里插入图片描述

1. 友元函数的定义和使用

友元函数在类中通过关键字friend声明,表示该函数被赋予访问该类的私有和受保护成员的权限。

#include <iostream>class MyClass {
private:int secret;public:MyClass(int val) : secret(val) {}// 声明友元函数,记住这个关键字 friend 面试官可能会问这个关键字friend void showSecret(MyClass &obj);
};// 友元函数的定义
void showSecret(MyClass &obj) {std::cout << "The secret is: " << obj.secret << std::endl;
}int main() {MyClass obj(42);showSecret(obj);  // 输出: The secret is: 42return 0;
}

在这里插入图片描述
在上面的例子中:

  • MyClass类有一个私有成员secret。
  • showSecret函数被声明为MyClass的友元函数,因此它可以直接访问MyClass对象的私有成员secret。

2. 友元函数的特性

在这里插入图片描述

3. 友元函数的用途

在这里插入图片描述

举个例子:操作符重载

#include <iostream>class Complex {
private:double real, imag;public:Complex(double r, double i) : real(r), imag(i) {}// 声明友元函数,用于重载+运算符,这样两个类对象就可以相加操作了friend Complex operator+(const Complex &c1, const Complex &c2);void display() const {std::cout << real << " + " << imag << "i" << std::endl;}
};// 定义友元函数
Complex operator+(const Complex &c1, const Complex &c2) {return Complex(c1.real + c2.real, c1.imag + c2.imag);
}int main() {Complex c1(1.5, 2.5), c2(3.0, 4.0);Complex c3 = c1 + c2;  // 调用友元函数c3.display();  // 输出: 4.5 + 6.5ireturn 0;
}

在这里插入图片描述

4. 友元函数的缺点和注意事项

在这里插入图片描述

102. 什么是观察者模式?

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

实现一个观察者模型

下面是一个简单的C++实现观察者模式的例子,模拟了一个天气预报系统。

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>// 观察者接口
class Observer {
public:virtual void update(float temperature, float humidity, float pressure) = 0;virtual ~Observer() = default;
};// 主题接口
class Subject {
public:virtual void registerObserver(Observer *observer) = 0;virtual void removeObserver(Observer *observer) = 0;virtual void notifyObservers() = 0;virtual ~Subject()  = default;
};// 具体的主题类(天气数据)
class WeatherData : public Subject {
private:std::vector<Observer*> observers;float temperature;float humidity;float pressure;public:void registerObserver(Observer *observer) override {if (std::find(observers.begin(), observers.end(), observer) == observers.end())observers.push_back(observer); }void removeObserver(Observer *observer) override {// std::remove(只是“重排”,不删元素), 把不等于 o 的元素“挤到前面”,并保持它们的相对顺序;把“不该删”的元素挤到前面,并返回“新的逻辑末尾”迭代器;不改变容器大小// 调用后,[first, new_end) 这段是你想保留的元素;[new_end, last) 是待丢弃的“尾巴”。// 它返回一个新的迭代器,指向容器中移除元素后的“新末尾”,即所有不等于 value 的元素之后的位置。// 删除 [first, last),包含 first,不包含 last。// 传入 new_end 和 end(),等价于“从新末尾删到原末尾”observers.erase(std::remove(observers.begin(), observers.end(), observer), observers.end());}void notifyObservers() override {for (Observer *observer : observers) {observer->update(temperature, humidity, pressure);}}// 模拟数据更新void setMeasurements(float temp, float hum, float press) {temperature = temp;humidity = hum;pressure = press;notifyObservers();}
};// 具体的观察者类
class CurrentConditionsDisplay : public Observer {
public:void update(float temperature, float humidity, float pressure) override {std::cout << "Current conditions: " << temperature << "C degrees and " << humidity << "% humidity." << std::endl;}
};int main() {WeatherData weatherData;CurrentConditionsDisplay currentDisplay;weatherData.registerObserver(&currentDisplay);weatherData.setMeasurements(45.0, 65.0, 1013.1);  // 模拟新的天气数据weatherData.setMeasurements(52.5, 70.0, 1012.5);  // 模拟新的天气数据return 0;
}

在这里插入图片描述

  • WeatherData:是主题(Subject),它维护了一个观察者列表,并在其数据变化时通知观察者。
  • CurrentConditionsDisplay:是观察者(Observer),它在接收到WeatherData的通知时,根据新的天气数据更新显示。

与发布订阅模式的区别

如果想严格区分 观察者模式 和 发布订阅模式的区别。请看下面的总结。
在这里插入图片描述

103. 虚函数说一下,虚函数和纯虚函数的区别?

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

104. 说说map和unordered_map的区别,实现方式

1. map 与 unordered_map 的区别

在这里插入图片描述

2. map 的实现方式:红黑树

map 是通过红黑树实现的,红黑树是一种自平衡二叉搜索树,确保在插入、删除、查找等操作后树的高度近似平衡,从而保证操作的时间复杂度为 O(log n)。

在这里插入图片描述

3. unordered_map 的实现方式:哈希表

unordered_map 通过哈希表实现,它利用哈希函数将键值映射到不同的桶(bucket),从而实现快速查找

在这里插入图片描述

4. 使用示例

使用 map

#include <iostream>
#include <map>int main() {std::map<int, std::string> myMap;myMap[1] = "One";myMap[3] = "Three";myMap[2] = "Two";// 按键的顺序输出for (const auto& [key, value] : myMap) {std::cout << key << ": " << value << std::endl;}return 0;
}

在这里插入图片描述

使用 unordered_map

#include <iostream>
#include <unordered_map>int main() {std::unordered_map<int, std::string> myUnorderedMap;myUnorderedMap[1] = "One";myUnorderedMap[3] = "Three";myUnorderedMap[2] = "Two";// 输出顺序不固定for (const auto& [key, value] : myUnorderedMap) {std::cout << key << ": " << value << std::endl;}return 0;
}

在这里插入图片描述

set 和 map 的区别

在这里插入图片描述

105. HTTPS加密方式

在这里插入图片描述

证书和颁发验证的过程示意图

在这里插入图片描述

之后我会持续更新,如果喜欢我的文章,请记得一键三连哦,点赞关注收藏,你的每一个赞每一份关注每一次收藏都将是我前进路上的无限动力 !!!↖(▔▽▔)↗感谢支持!

http://www.xdnf.cn/news/1283797.html

相关文章:

  • wrap cpp variant as dll for c to use
  • day48 力扣739. 每日温度 力扣496.下一个更大元素 I 力扣503.下一个更大元素II
  • 力扣热题100-----322.零钱兑换
  • 使用docker compose 部署dockge
  • scikit-learn/sklearn学习|岭回归解读
  • Mybatis学习之逆向工程(十)
  • Python 类元编程(类工厂函数)
  • Vue 3 快速入门 第六章
  • 【MATLAB 2025a】安装离线帮助文档
  • web前端第三次作业
  • Azimutt:一款免费开源的多功能数据库工具
  • Linux下安装jdk
  • C语言(06)——二、八、十、十六进制的相互转换
  • 机器学习 TF-IDF提取关键词,从原理到实践的文本特征提取利器​
  • 稠密检索:基于神经嵌入的高效语义搜索范式
  • 【CSS 布局】告别繁琐计算:CSS 现代布局技巧(gap, aspect-ratio, minmax)
  • Wed前端第二次作业
  • 【Node.js从 0 到 1:入门实战与项目驱动】1.4 Node.js 的发展与生态(历史版本、LTS 版本、npm 生态系统)
  • 【LeetCode 热题 100】(七)链表
  • 5G NR NTN 在 PHY 层和 MAC 层实现 OAI
  • 软考 系统架构设计师系列知识点之杂项集萃(121)
  • 深入解析Windows系统下UDP绑定失败的原理与系统级解决方案
  • SQL中BETWEEN与IN的差异详解
  • ERA5---MATLAB处理水汽数据与臭氧数据的读取与重采样-重复性工作
  • Linux系统编程Day12 -- 环境变量(初识)
  • Flutter学习笔记(六)---状态管理、事件、路由、动画
  • MCU 软件断点注意事项!!!
  • LVPECL、LVDS、LVTTL、LVCMOS四种逻辑电平标准的全面对比
  • C# 异步编程(BeginInvoke和EndInvoke)
  • GPT-5 全面解析与最佳实践指南