yhy's blog
new操作符用于动态分配内存并构造对象。重载该函数并与宏定义相配合可以很好的检测出内存泄漏的地方在哪里正常重载new运算符的语法为 void* operator new(std::size_t sz) 我们可以使用void* operator new(std::size_t size, const char* file, int line);void* operator new[](std::size_t size, const char* file, int line);这两种形式来重载,想要使用new的时候调用我们重载的new 还要定义一个宏#define new new (__FILE__, __LINE__)这样我们就可以根据__FILE__文件名 加 __LINE__ 行号去找到申请内存的位置,从而定位检测内存泄漏
volatile 关键字在多线程编程中的一个重要作用是防止编译器对代码进行优化,以确保变量的读写操作不会被重排或优化掉。这与指令重排有关。指令重排是现代处理器为了提高性能而采取的一种优化手段,它允许处理器在不改变程序语义的前提下重新排序指令执行顺序,以充分利用处理器的并行执行能力和提高性能。然而,在多线程环境下,指令重排可能导致程序出现意外行为,特别是在涉及到多线程共享变量的情况下。volatile 关键字告诉编译器,被 volatile 修饰的变量可能会被其他线程或外部因素修改,因此编译器不应该对这些变量的读写操作进行优化或重排。具体来说,volatile 的作用包括:禁止编译器优化:编译器在生成汇编代码时,会保证 volatile 变量的读写操作按照代码中的顺序执行,不会进行指令重排优化。保证内存可见性:volatile 变量的读写操作会直接操作内存,而不会被缓存,从而保证了多线程之间对变量的修改能够及时可见。
! > 算术运算符 > 关系运算符 > && > || > 赋值运算符 > 逗号运算符
高内聚(High Cohesion):指一个模块或一个类内部各个元素(方法、属性等)彼此关联紧密,共同完成一个特定的任务或功能。高内聚性意味着模块内部各个元素之间的联系紧密,功能相关,实现了单一职责原则。一个高内聚的模块应该专注于完成一个具体的任务,而不包含与其无关的功能。低耦合(Low Coupling):指不同模块或类之间的依赖关系尽可能的降低。低耦合性意味着模块之间的依赖关系简单、松散,一个模块的修改不会对其他模块造成影响。模块之间通过接口进行通信,而不是直接依赖于彼此的内部实现。
智能指针都是非线程安全的
封装(Encapsulation):封装是指将数据(属性)和操作数据的方法(方法)捆绑在一起,形成一个独立的单元。对象的内部实现对外部隐藏,外部只能通过对象提供的接口来访问和操作对象的数据。继承(Inheritance):继承是指一个对象(子类)可以继承另一个对象(父类)的属性和方法,从而可以重用父类的代码并扩展其功能。通过继承,可以建立对象之间的层次关系,提高代码的复用性和可维护性。多态(Polymorphism):多态是指同一个方法调用可以根据对象的不同表现出不同的行为。通过多态,可以实现方法的重载(Overloading)和方法的重写(Overriding),使得程序更加灵活和可扩展。
可以调用,但是没有动态绑定的效果,父类构造函数中调用的仍然是父类版本的函数,子类中调用的仍然是子类版本的函数。构造过程构造函数会先调用父类构造函数,而如果构造函数中有虚函数,此时子类还没有构造,所以此时的对象还是父类的,不会触发多态。析构过程中子类先进行析构,这时,如果有virtual函数的话,子类的内容已经被析构了,C++会视其父类,执行父类的virtual函数。
std::function简单而言就是一个函数包装器,一个通用函数类型头文件 #include <functional>用法:function<int(int, int)> 里面传入的是返回值 和参数列表示例#include <iostream> #include <functional> using namespace std; void vfun() { cout << "void fun()" << endl; } int ifun(int a) { cout << "int fun(int a)" << endl; return 0; } int main() { // Your code here function<void()> _vf = vfun; // 接收函数指针 function<int(int)> _if = ifun; f
例如printf 和 scanf 函数的定义,他们可以使用不确定数量的参数声明方式为:int func_name(int arg1, ...);省略号 ... 表示可变参数列表。在函数中使用这些参数使用 stdarg.h 头文件在函数定义中创建一个 va_list 类型变量,该类型是在 stdarg.h 头文件中定义的。使用 int 参数和 va_start() 宏来初始化 va_list 变量为一个参数列表。宏 va_start() 是在 stdarg.h 头文件中定义的。使用 va_arg() 宏和 va_list 变量来访问参数列表中的每个项。使用宏 va_end() 来清理赋予 va_list 变量的内存。示例#include <iostream> #include <cstdarg> using namespace std; void fun(int argc, ...) //argc代表参数的数量 { va_list vlst; /* 为 argc 个参数初始化 vlst */ va_start(vlst, argc);
函数原型int stoi (const string& str, size_t* idx = 0, int base = 10);str : 要转换为数字的字符串idx : 传出参数,当std::stoi无法解析整个字符串时,idx将被设置为第一个无法解析的字符的索引,传入NULL代表不使用这个参数base: 确定以何种的进制去解释str中的数值
lelele