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

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

文章目录

  • 136. 什么是拷贝控制?包括哪些内容?
    • 拷贝构造函数
    • 拷贝赋值运算符
    • 析构函数
    • 移动构造函数
    • 移动赋值运算符
  • 137. Socket网络编程你做过吗?说说建立TCPSocket的函数名是什么?和UDPSocket 的关键参数区别是什么?
    • 建立 TCP Socket 的函数名
    • 建立 UDP Socket 的函数名
    • TCP 和 UDP 的关键参数区别
  • 138. 大数据中找中位数,谈谈你的思路。
    • 分桶思维
    • 核心步骤
    • 示例(体会一下整个思路):将数据分桶并定位中位数
  • 139. 对称加密和非对称加密有什么区别?说出一种对称加密算法。
    • 核心区别
    • 实际应用
    • 一种对称加密算法
  • 140. STL 容器的 sort()使用了哪种排序算法?
    • 快排实现代码

136. 什么是拷贝控制?包括哪些内容?

在 C++ 中,拷贝控制 是一组用于管理对象如何被拷贝、赋值和销毁的机制。拷贝控制的目的是确保对象的资源(如内存、文件句柄等)能够在对象拷贝或赋值时正确地被管理,防止出现资源泄漏或浅拷贝的问题。

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

拷贝构造函数

在这里插入图片描述

ClassName(const ClassName& other);

默认的赋值运算符执行的是 浅拷贝,即将一个对象的数据成员的值复制给另一个对象的对应成员。

在 obj3 = obj1; 执行时,obj3 的 data 成员会指向 obj1 的 data 内存,而在 obj3 析构时会尝试删除相同的内存,导致 双重删除(double delete),进而导致程序崩溃。

#include <iostream>class MyClass {
private:int* data;public:// 构造函数MyClass(int value) : data(new int(value)) {std::cout << "Constructor: Allocated memory for value " << value << std::endl;}// 拷贝构造函数MyClass(const MyClass& other) {data = new int(*other.data); // 注意这里使用了深拷贝:分配新内存并复制值std::cout << "Copy Constructor: Copied value " << *other.data << std::endl;}// 析构函数~MyClass() {std::cout << "Destructor: Deleting value " << *data << std::endl;delete data; // 释放动态分配的内存}// 显示值void display() const {std::cout << "Value: " << *data << std::endl;}
};int main() {MyClass obj1(42);  // 调用构造函数obj1.display();// 使用拷贝构造函数MyClass obj2 = obj1;  // 调用拷贝构造函数obj2.display();// 修改 obj1 的值,验证深拷贝是否有效{MyClass obj3(99); // 创建一个新的对象obj3 = obj1;      // 注意:这里是赋值操作,不是拷贝构造} // obj3析构return 0;
}//这里我说一个重点区分。就是要区分 拷贝构造 和 拷贝赋值,不然我们会傻傻分不清。
//拷贝构造函数用于新对象的初始化,即用一个已有的对象初始化另一个新创建的对象。强调这个新字。
//赋值运算符用于赋值操作,即当一个已有的对象将另一个已有对象的内容复制到自身时触发。强调“已有”。

在这里插入图片描述

拷贝赋值运算符

  • 拷贝赋值运算符用于将一个对象的值赋给另一个已经存在的对象。它会在以下情况下被调用:
    • 当使用 = 运算符将一个对象赋值给另一个对象时。
ClassName& operator=(const ClassName& other);
class MyClass {
private:int* data;
public:MyClass(int value) : data(new int(value)) {}// 拷贝赋值运算符MyClass& operator=(const MyClass& other) {if (this == &other) {return *this;  // 自赋值检查}delete data;  // 释放原有资源data = new int(*other.data);  // 复制新数据return *this;}
};

析构函数

  • 析构函数用于销毁对象,释放对象占用的资源。当对象生命周期结束时(如超出作用域时),析构函数会自动调用。
~ClassName();
class MyClass {
private:int* data;
public:MyClass(int value) : data(new int(value)) {}// 析构函数~MyClass() {delete data;  // 释放资源}
};

移动构造函数

  • 移动构造函数用于通过“偷取”资源(而非拷贝)来初始化一个新对象从而避免不必要的资源复制。它在 C++11 引入,适用于需要高效移动的类(如 std::vector)。
ClassName(ClassName&& other) noexcept;
#include <iostream>
#include <utility> // std::moveclass MyClass {
private:int* data;public:// 构造函数MyClass(int value) : data(new int(value)) {std::cout << "Constructor: Allocated memory for value " << value << std::endl;}// 移动构造函数MyClass(MyClass&& other) noexcept {data = other.data;        // “偷取”资源other.data = nullptr;     // 将原对象的指针置空,防止析构时重复释放std::cout << "Move Constructor: Transferred ownership" << std::endl;}// 拷贝构造函数MyClass(const MyClass& other) {data = new int(*other.data); // 深拷贝std::cout << "Copy Constructor: Copied value " << *data << std::endl;}// 析构函数~MyClass() {if (data) {std::cout << "Destructor: Deleting value " << *data << std::endl;delete data; // 释放动态内存} else {std::cout << "Destructor: No resource to delete" << std::endl;}}// 显示值void display() const {if (data) {std::cout << "Value: " << *data << std::endl;} else {std::cout << "No data available" << std::endl;}}
};int main() {// 创建对象MyClass obj1(42);  // 调用普通构造函数obj1.display();// 使用移动构造函数MyClass obj2(std::move(obj1));  // 调用移动构造函数obj2.display();obj1.display();  // obj1 的资源已被转移,变为空// 创建一个新对象并使用拷贝构造函数MyClass obj3 = obj2;  // 调用拷贝构造函数obj3.display();return 0;
}

在这里插入图片描述

移动赋值运算符

  • 移动赋值运算符与移动构造函数类似,也是通过“偷取”资源来避免不必要的资源复制。它用于将一个对象的资源转移到另一个对象,并释放目标对象原本的资源。
ClassName& operator=(ClassName&& other) noexcept;
#include <iostream>
#include <utility> // std::moveclass MyClass {
private:int* data;public:// 构造函数MyClass(int value) : data(new int(value)) {std::cout << "Constructor: Allocated memory for value " << value << std::endl;}// 拷贝构造函数MyClass(const MyClass& other) : data(new int(*other.data)) {std::cout << "Copy Constructor: Copied value " << *data << std::endl;}// 移动赋值运算符MyClass& operator=(MyClass&& other) noexcept {if (this != &other) {delete data;         // 释放现有资源data = other.data;   // "偷取"资源other.data = nullptr; // 将源对象的数据指针置为 nullptrstd::cout << "Move Assignment Operator: Transferred ownership" << std::endl;}return *this;}// 析构函数~MyClass() {if (data) {std::cout << "Destructor: Deleting value " << *data << std::endl;delete data; // 释放动态分配的内存} else {std::cout << "Destructor: No resource to delete" << std::endl;}}// 显示值void display() const {if (data) {std::cout << "Value: " << *data << std::endl;} else {std::cout << "No data available" << std::endl;}}
};int main() {// 创建对象MyClass obj1(42);  // 调用普通构造函数obj1.display();MyClass obj2(84);  // 调用普通构造函数obj2.display();// 使用移动赋值运算符obj2 = std::move(obj1);  // 调用移动赋值运算符obj2.display();obj1.display();  // obj1 的资源已被转移,变为空return 0;
}

在这里插入图片描述

137. Socket网络编程你做过吗?说说建立TCPSocket的函数名是什么?和UDPSocket 的关键参数区别是什么?

Socket 网络编程 是服务器后端开发的基础之一。

建立 TCP Socket 的函数名

TCP Socket 是基于连接的流协议,提供可靠的数据传输。建立 TCP Socket 的常用函数及其作用如下:

在这里插入图片描述

建立 UDP Socket 的函数名

UDP Socket 是无连接的、基于数据报的协议,不保证可靠性,但传输效率高。建立 UDP Socket 的常用函数如下:

在这里插入图片描述

TCP 和 UDP 的关键参数区别

在这里插入图片描述

138. 大数据中找中位数,谈谈你的思路。

分桶思维

分桶/直方图方法主要通过将数据分成多个区间(或桶),根据桶中的元素数量来快速定位中位数。其核心思想是利用数据的分布特性,减少每次查找中位数的计算复杂度。
在这里插入图片描述

大概思路:
在大数据或流式数据的场景中,直接对所有数据排序可能不现实。分桶法通过将数据映射到多个“桶”(区间)中,每个桶表示一定范围的数据。通过统计各桶中元素的数量,快速找到包含中位数的桶,再从该桶中精确地确定中位数。

核心步骤

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

示例(体会一下整个思路):将数据分桶并定位中位数

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

139. 对称加密和非对称加密有什么区别?说出一种对称加密算法。

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

核心区别

在这里插入图片描述

实际应用

  • 对称加密:用于大数据加密传输,因为速度快,比如 HTTPS 通信中的会话数据加密
  • 非对称加密:常用于密钥交换、数字签名,比如 HTTPS 中的密钥协商过程

一种对称加密算法

在这里插入图片描述

140. STL 容器的 sort()使用了哪种排序算法?

在 C++ STL 中,std::sort() 函数使用了一种 混合排序算法,通常是 Introsort(内省排序)。

#include <iostream>
#include <vector>
#include <algorithm>int main() {std::vector<int> data = {10, 5, 8, 3, 7};std::sort(data.begin(), data.end()); // 调用 Introsortfor (const auto& num : data) {std::cout << num << " ";}return 0;
}

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

//理想情况
[10, 2, 8, 7, 1] -> 分区后 -> [2, 1] [8, 10, 7]
//最坏情况
[1, 2, 3, 4, 5] -> 分区后 -> [] [2, 3, 4, 5]

快排实现代码

#include <bits/stdc++.h>using namespace std;int partition(vector<int>& v, int left, int right) {int pivot = v[left];while(left < right) {while(left < right && v[right] >= pivot) {--right;}if(left < right) {v[left] = v[right];}while(left < right && v[left] <= pivot) {++left;}if(left < right) {v[right] = v[left];}}v[left] = pivot;return left;
}void quickSort(vector<int>& v, int left, int right) {if(left < right) {int pos = partition(v, left, right);quickSort(v, left, pos - 1);quickSort(v, pos + 1, right);}
}int main() {vector<int> a = {15, 3, 6, 0, 1};quickSort(a, 0, 4);for(const int & num: a) {cout<< num<< " ";}cout << endl;return 0;
}

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

http://www.dtcms.com/a/339234.html

相关文章:

  • 数据库-MYSQL配置下载
  • 前端性能优化实战手册:从网络到运行时,一套可复制落地的清单
  • 基于提示词工程和MCP构建垂直Agent应用
  • Go语言中的优雅并发控制:通道信号量模式详解
  • JS 中的 this
  • AI-调查研究-55-机器人 百年进化史:从Unimate到人形智能体的技术跃迁
  • Navicat 使用超详细教程:从下载到实战案例
  • Vue.prototype 的作用
  • AJAX (一)
  • 【深度学习-pytorch】mnist数字识别
  • Java 大视界 -- Java 大数据机器学习模型在自然语言处理中的多语言翻译与文化适应性优化
  • go.uber.org/zap 日志库高性能写入
  • 结合BI多维度异常分析(日期-> 商家/渠道->日期(商家/渠道))
  • 常见BI工具
  • 变电站智能辅助监控系统:结构框架、功能模块及配套设备指南
  • 【国内电子数据取证厂商龙信科技】Python数据分析环境搭建
  • 科技云报到:AI推理破局,金融服务如何“逆天改命”
  • JavaWeb开发笔记合集
  • 工厂MES管理系统的五大核心应用场景
  • 功能上新:燕千云ITSM如何让高频重复问题自动总结推送
  • Cursor+Apifox MCP Server接口自动化新范式探索
  • 二分法专题训练
  • 基础分类决策树
  • 疯狂星期四文案网第44天运营日记
  • 力扣hot100:找到字符串中所有字母异位词(滑动窗口 + 字符频率数组)(438)
  • Java实现一个加法运算
  • 《Java 多线程全面解析:从基础到生产者消费者模型》
  • 基于Paddle和YOLOv5实现 车辆检测
  • Markdown to PDF/PNG Converter
  • 浅看架构理论(二)