C++右值

在C++98时代,我们经常会遇到这样的性能瓶颈:当需要返回或传递大型对象(如字符串、向量或自定义资源管理类)时,不得不进行昂贵的深拷贝操作。即使我们知道某些对象即将被销毁,也无法避免这种拷贝开销。 C++11引入的右值引用和移动语义彻底改变了这一局面,让C++程序员能够写出更高效、更现代的代码。

C++语言

C++智能指针

C++从C++11开始引入了智能指针(std::unique_ptr、std::shared_ptr、std::weak_ptr),并后面的各个版本中对智能指针进行了改进。

C++语言

从C++11开始新增的常用关键字

nullptr (C++11)nullptr 专门用于表示空指针,旨在解决传统 NULL 或 0 在类型安全性和代码清晰度上的缺陷。 nullptr 的类型为 std::nullptr_t,只能隐式转换为指针类型(包括原生指针、智能指针、托管句柄等),​不能转换为整数类型,避免了与整型 0 的混淆。 而传统 NULL 是宏(通常定义为 0 或 (void*)0),可能被误解释为整数,导致类型错误。

C++语言

C++异常之我所见

C++异常所带来的问题当我们在代码中写下一行 throw 语句时,我们就此埋下了一个祸根,从此以后,在该函数调用链中,必须至少有一个调用者需要提供相应的异常捕获,否则一旦异常被抛出,程序就会异常终止。 例如,函数 f() 调用 g(),而 g() 又调用 h(),并且 h() 抛出一个异常,则 g() 和 f()中必须有一个提供了相应的异常捕获,否则程序会异常终止。 由于异常会使代码的执行流程从任意地方跳出,因此我们还需要付出大量的精力来编写正确的异常安全代码,例如使用 RAII(资源获取即初始化)来保证资源正确释放。 如下面的示例,虽然我们在函数 f() 中捕获了异常,避免了程序的异常终止,但异常却中断了函数 g() 的正常执行流程,导致对象 m 没有被正确释放,从而出现了资源泄露。这种情况可能还会变相地增加了程序的调试难度。

C++语言

如何通过结构体成员地址获取父地址

有如下结构体: 12345678struct Test { int a; // .... // 还有若干成员 // ... int y; int z;}; 在只知道成员变量y地址的情况下,如何获取到结构体的首地址?

C++语言

C/C++不同整数类型的区别

在C/C++中涉及的整数相关的类型大致有如下几种: char、unsigned char short、unsigned short int、unsigned int long、unsigned long long long、unsigned long long int8_t、uint8_t int32_t、uint32_t int64_t、uint64_t DWORD DWORD32、DWORD64 size_t、ssize_t SIZE_T、SSIZE_T

C++语言

C++字符串和字符字面量

C++ 支持各种字符串和字符类型,并提供了表达每种类型字面值的方法。在源代码中,我们使用字符集来表示字符或字符串。同时我们还可以使用通用字符名和转义字符来通过基本的源字符集表示任何字符串。而原始字符串能够避免对转义字符进行转义,并可用于表示所有类型的字符串。

C++语言

LLVM-Obfuscator代码混淆

LLVM-Obfuscator 可用于混淆程序的代码逻辑,本文介绍如何使用 LLVM-Obfuscator 进行代码逻辑的混淆。

C++语言

C++构造函数排雷

一、默认构造函数1.1 什么是默认构造函数?我们一般会认为默认构造函数就是编译器自动生成的那个构造函数,其实这种理解不全面。准确的说,默认构造函数就是在调用时不需要显示地传入实参的构造函数。根据这个原则,下面 2 种构造函数都是默认构造函数: 1234567class Sample {public: // 默认构造函数。 Sample() { // do something }}; 1234567class Sample {public: // 默认构造函数。虽然有形参,但有默认值,调用时可以不显式地传入实参。 Sample(int m = 10) { // do something }};

C++语言

C++生成条形码

条形码(barcode)是将宽度不等的多个黑条和空白,按照一定的编码规则排列,用以表达一组信息的图形标识符。常见的条形码是由反射率相差很大的黑条(简称条)和白条(简称空)排成的平行线图案。

C++语言

C++ 默认构造函数

本文围绕 3 个问题来理解 C++的默认构造函数: 什么是默认构造函数? 默认构造函数什么时候被调用? 编译器在什么情况下会生成默认构造函数?

C++语言

C++内存池实现

本文从实际需求出发,介绍了内存池的实现原理,并且提供了具体的实现方案。 一、为什么需要使用内存池在 C/C++ 中我们通常使用 malloc、free或new、delete 来动态分配内存。一方面,因为这些函数涉及到了系统调用,所以频繁的调用必然会导致程序性能的损耗; 另一方面,频繁的分配和释放小块内存会导致大量的内存碎片的产生,当碎片积累到一定的量之后,将无法分配到连续的内存空间,系统不得不进行碎片整理来满足分配到连续的空间,这样不仅会导致系统性能损耗,而且会导致程序对内存的利用率低下。 当然,如果我们的程序不需要频繁的分配和释放小块内存,那就没有使用内存池的必要,直接使用malloc,free或new,delete函数即可。

C++语言
12