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(¤tDisplay);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加密方式
证书和颁发验证的过程示意图
之后我会持续更新,如果喜欢我的文章,请记得一键三连哦,点赞关注收藏,你的每一个赞每一份关注每一次收藏都将是我前进路上的无限动力 !!!↖(▔▽▔)↗感谢支持!