完美转发
C++ 中的“完美转发”(Perfect Forwarding)。核心含义: 完美转发是指在函数模板中,将接收到的参数以其原本的值类别(左值或右值)和 const/volatile 属性转发给另一个函数。 简单来说,就是让一个“中间”函数(通常是模板函数)能够透明地将参数传递给它调用的“目标”函数,就好像参数是直接传递给目标函数一样,不会因为经过中间函数而改变参数的左值/右值属性或 const/volatile 属性。 为什么需要完美转发? 考虑一个常见的场景:你有一个泛型函数(比如一个包装器、一个工厂函数、一个日志记录函数),它接收任意类型的参数,然后将这些参数传递给另一个实际执行操作的函数。 例如: 123456789101112131415161718192021222324252627282930313233343536373839404142void target_function(int& arg) { std::cout << "Called with lvalue: "...
移动语义的方方面面
主播刚刚考完计算机组成原理哈,然后浅浅荒废了几天的时间,leetcode也没刷,八股也没看,不过计算机组成原理终究是过了,姑且算对计算机有了更深入的一点点了解,过几天的信号与系统和电动力学才是折磨。 碎碎念结束。 ———————————————————————————————————————————————————————————— c++11中引入了一个经常见到的函数,std::move,初次见面是在unique_ptr那一节中,后来在移动构造函数中也有见面,它的作用可以简单的理解为实现将左值转换为右值。 那么我们首先介绍一下什么是左值和右值。 左值和右值左值,可以理解为有内存地址的值,与之相对,右值就是没有内存地址的值。 从硬件上说,左值由内存存储,右值由寄存器存储,所以右值就是马上就要消亡的值,生命周期一般只有所在的那一行代码 常见的右值形式包括: 1.int x = 5;里面的5等常量 2.调用函数的返回值 3.算术表达式或者逻辑表达式 而左值就是我们常说的变量及所有可以被左赋值的值 从而我们得到了左值引用和右值引用 123int a=1;int...
手撕vector
...
运算符重载与友元函数
众所周知,运算符重载作为多态的一种实现,使用是较为普遍的 但是重载运算符,本身是几元就有几个参数,对于二元运算符,第一个参数对应左侧运算对象,第二个参数对应右侧运算对象 而重载运算符作为类的成员函数的时候,第一个参数就隐式绑定了this指针,即左侧运算对象固定为this指针 举个最常见的拷贝赋值重载函数例子 1234567891011121314151617class DeepCopy{public: int *data; //省略构造函数 DeepCopy& operator=(const DeepCopy &other) { if(this!=other) { delete data; data=new int (*(other.data)); } return *this; }};DeepCopy a,b;a=b; 但是,我们难免会遇到非成员函数重载的情况,此时我们就要借助友元函数或者全局函数,但友元函数相对更为常规,比如以下例子 1....
友元与友元函数
友元与友元函数在 C++ 中,友元(friend)是一种机制,允许特定的非成员函数或类访问某个类的私有(private)和保护(protected)成员,从而在一定程度上绕过封装限制。友元函数和友元类是友元机制的两种主要形式。以下是详细说明。 1. 友元函数友元函数是一个非成员函数,但通过在类中用 friend 关键字声明,获得访问该类私有和保护成员的权限。 特点 非成员函数:友元函数不属于类的成员,不能通过类的对象直接调用(如 obj.func()),而是像普通全局函数一样调用。 访问权限:可以直接访问类的私有和保护成员,通常需要通过对象参数传递。 声明位置:在类中用 friend 关键字声明,可位于 public、private 或 protected 区域(位置不影响功能)。 调用方式:通过函数名直接调用,通常传递类对象作为参数。 语法123456789101112class MyClass {private: int value;public: MyClass(int v) : value(v) {} friend...
cpu的乱序执行与内存顺序
乱序执行是现代高性能处理器(CPU)中一种非常重要的性能优化技术。它的核心思想是:CPU 不严格按照程序代码中指令的顺序来执行它们,而是根据指令是否“准备好”来决定执行顺序,但最终要保证程序的结果与按顺序执行时一致。 为什么需要乱序执行? 传统的 CPU 执行模式是**顺序执行 (In-Order Execution)**:CPU 严格按照程序代码的指令顺序一条接一条地执行。然而,这种方式效率不高,原因在于: 指令依赖 (Instruction Dependencies): 后一条指令可能需要等待前一条指令的结果才能执行。例如: 12ADD R1, R2, R3 ; R1 = R2 + R3SUB R4, R1, R5 ; R4 = R1 - R5 (需要等待 ADD 指令的结果 R1) 在顺序执行中,SUB 指令必须等待 ADD 指令完成后才能开始。这会造成 CPU 的执行单元(如算术逻辑单元 ALU)在这段时间内处于空闲状态,浪费了计算资源。 内存延迟 (Memory Latency):...
inline内联函数的使用
又是好久没有更新了,家人们,主播最近写完了c++的几个轮子项目,工程能力有了一内内的提高,现在在准备八股,希望暑假or大三能找到一个满意的实习吧(虽然就目前来看,c++全是劝退,我真服了,后悔没有选java了,后面主播慢慢转go吧) 在C++中,inline 关键字主要用于定义内联函数,具有以下两个主要作用: 优化性能:使用 inline 修饰的函数,建议编译器在调用该函数时,将函数体的代码直接插入到调用点。 相比正常的函数调用过程:寄存器保存,参数压栈,跳转到函数地址,执行函数体,返回并恢复寄存器 这可以减少函数调用的开销,尤其适用于小型、频繁调用的函数。例如: 1inline int square(int x) { return x * x; } 当调用 square(5) 时,编译器可能将代码替换为 5 * 5,避免函数调用开销。注意:inline 只是建议,编译器可能忽略它,尤其在以下情况下: 函数体过大 函数包含循环、递归、静态变量、switch 或 goto 语句 函数地址被取用(如通过函数指针) 允许多个定义:inline...
c++中的多线程写时复制
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586#include<iostream>#include<mutex>#include<memory>#include<shared_mutex>using namespace std;//写时复制包装器模板类template<typename T>class CowPtr{private: mutable shared_ptr<T> ptr; //mutable 关键字允许在 const 方法中修改这个成员变量 mutable shared_mutex mutex;//mutable 关键字允许在 const...
再探智能指针
又是许久未见的一期非人机博客,哈哈哈,感觉事好多(才不是寒假偷懒) 写完cc_muduo网络库之后,深感c++基础有待加深学习,于是重新看了一遍智能指针 众所周知,智能指针包括三种shared_ptr,weak_ptr,unique_ptr,我们一个个来 shared_ptr智能指针,作为c++独有的方式,相比malloc,free,以及new...
bind和回调函数的关系
回调(Callback)函数回调函数是一种设计模式,指的是将一个函数作为参数传递给另一个函数,并在某个事件发生时由后者调用这个函数。简单来说,回调函数是被“回调”执行的函数。 回调函数的作用 允许你在程序中实现灵活的控制流。 通过回调,你可以将具体的业务逻辑交给调用者来定义,而不是在框架或库中硬编码。 回调函数的典型示例123456789101112131415161718#include <iostream>using namespace std;// 回调函数类型void callback(int x) { cout << "Callback function called with value: " << x << endl;}// 使用回调的函数void processData(void (*cb)(int)) { int data = 42; cb(data); // 调用回调函数}int main() { ...




