写在前面:我们平时使用C++编程的时候,可能更多的时候关注的是完成指定任务或实现某一功能即可,对于性能方面(内存开销,计算快慢等),大多数时候被忽视了。对于一些资源比较少的处理器,那我们就需要在编程过程中时刻关注资源的使用,其实C++内部提供了一些技巧,能够帮助我们优化代码性能。

目录

一、空间优化

1.1 引用传参

1.2 移动语义(右值引用&&)

1.3 禁用无用的默认操作

二、时间优化

2.1 内联函数

2.2 移动语义(右值引用&&)

2.3 std::vector技巧

2.4 emplace_back替代push_back

2.5 字符串拼接 "+"

2.6 减少循环内计算

2.7 减少浮点运算

三、内存管理


一、空间优化

1.1 引用传参

函数参数传递的时候可以使用引用传递,引用不会额外增加栈空间,特别是当传递的类的数据结构比较庞大的时候,引用传递能够大大减小栈资源的消耗,避免“爆栈”的危险发生。

#include <iostream>
#include <string>
#include <vector>

//包含大量成员变量/数据
class A {
public:
    // 构造函数:初始化大量数据(庞大对象)
    A(int id) 
        : m_id(id), m_bigData(1000000, 1.0) { // 百万级double数组
        std::cout << "A 构造函数执行(对象创建)\n";
    }

  
    // 析构函数
    ~A() {
        std::cout << "A 析构函数执行(对象销毁)\n";
    }

    // 成员方法:获取/修改数据
    int getId() const { return m_id; }

    // 打印对象信息
    void printInfo() const {
        std::cout << "ID: " << m_id << ", 大数据量大小: " << m_bigData.size() << "\n";
    }

private:
    int m_id;                      // 普通成员
    std::vector<double> m_bigData; // 百万级数据(庞大内存占用)
};
}

int main() {
    //采用引用传参,避免构建临时变量,占用过多栈资源
    void func(Class A & f_a)
    {
       //函数体
    }

    //错误方法:值传递,消耗太多栈资源
    //void func(Class A f_a)
    //{
    //   //函数体
    //}

    return 0;
}

1.2 移动语义(右值引用&&)

避免开辟额外的堆内存。移动语义的详细内容可参考之前的文章:C++ 右值引用-CSDN博客

1.3 禁用无用的默认操作

类中用 =delete 禁用不需要的拷贝构造 / 赋值运算符,减少编译器生成冗余代码。

#include <iostream>
using namespace std;

// 简单类:禁用拷贝构造和拷贝赋值
class B {
public:
    // 普通构造函数(显式声明,避免编译器默认生成的干扰)
    B(int num) : num_(num) {
        cout << "构造对象:" << num_ << endl;
    }

    // ========== 禁用拷贝构造和拷贝赋值 ==========
    B(const B&) = delete;                // 禁用拷贝构造
    B& operator=(const B&) = delete;     // 禁用拷贝赋值

    // 普通成员函数(测试用)
    void show() const {
        cout << "当前对象值:" << num_ << endl;
    }

private:
    int num_; // 简单成员变量
};

二、时间优化

2.1 内联函数

内联是C++对函数的一种特殊修饰,内联函数可以更形象地被称为内嵌函数。编译器进行代码编译时,如果发现某段代码调用是一个内联函数,那么它就将该函数的代码直接插入当前函数调用的位置,这样就省去了函数调用过程中的那些繁琐的幕后工作,提高了代码的运行效率,这样就以程序空间的增加换取了执行时间的减少。

#include <iostream>
using namespace std;

// ========== 核心:内联函数定义(inline 关键字) ==========
// 适合:代码量少(几行)、调用频繁的简单函数
inline int add(int a, int b) {
    return a + b; // 简单逻辑,无复杂分支/循环
}

int main() {
    // 调用内联函数(编译器尝试将代码嵌入此处)
    int sum = add(3, 5);
    cout << "3 + 5 = " << sum << endl;
    
    return 0;
}

2.2 移动语义(右值引用&&)

避免拷贝开销,直接“窃取”资源。 移动语义的详细内容可参考之前的文章:C++ 右值引用-CSDN博客

class Vector {
public:
    int* ptr;
    size_t size;
   
    // 构造函数
    Vector(size_t sz) : size(sz), ptr(new int[sz]) {
        std::cout << "构造函数" << std::endl;
    }
   
    // 拷贝构造函数(深拷贝)
    Vector(const Vector& other) : size(other.size), ptr(new int[other.size]) {
        std::cout << "拷贝构造函数" << std::endl;
        std::copy(other.ptr, other.ptr + other.size, ptr);
    }

    // 移动构造函数(窃取资源)
    Vector(Vector&& other) noexcept 
        : size(other.size), data(other.data) { // 直接复制指针!
        std::cout << "移动构造函数" << std::endl;
        // 将源对象置于有效但空的状态
        other.data = nullptr;
        other.size = 0;
    }
};
   
    ~Vector() { delete[] ptr; }
};

2.3 std::vector技巧

std::vector提前使用reserve(n)预留空间,避免多次扩容(扩容会拷贝所有元素)。

2.4 emplace_back替代push_back

push_back需要先构造/拷贝元素再插入,与push_back相比,emplace_back可在容器内存中直接构造,效率更高。

#include <iostream>
#include <vector>
#include <string>
using namespace std;

class Person {
public:
    // 普通构造函数
    Person(string f_name, int f_age) : name(f_name), age(f_age) {
        cout << "构造 Person:" << name << endl;
    }

    // 拷贝构造函数
    Person(const Person& other) : name(other.name), age(other.age) {
        cout << "拷贝构造 Person:" << name << endl;
    }

    // 移动构造函数(C++11)
    Person(Person&& other) noexcept : name(move(other.name)), age(other.age) {
        cout << "移动构造 Person:" << name << endl;
    }

private:
    string name;
    int age;
};

int main() {
    vector<Person> vec;
    vec.reserve(10); // 预分配内存,避免扩容干扰

     cout << "\n===== push_back 传入已有对象 =====" << endl;
    Person p("Charlie", 18);
    vec.push_back(p); // 拷贝构造(无移动,因为是左值)

    cout << "===== push_back 传入临时对象 =====" << endl;
    // push_back:先构造临时对象 → 移动到容器(C++11后优化)
    vec.push_back(Person("Alice", 20));

    cout << "\n===== emplace_back 传入构造参数 =====" << endl;
    // emplace_back:直接在容器内存中构造,无拷贝/移动
    vec.emplace_back("Bob", 25);

    return 0;
}

2.5 字符串拼接 "+"

随意使用字符串拼接符号"+",容易造成性能变慢(特别是在循环内进行拼接的时候)

std::string result = "";
for (int i = 0; i < 10000; i++) {
    result = result + "a";  // 会创建临时变量,拷贝旧内容
}

建议使用append方法替代:

for (int i = 0; i < 10000; i++) {
   result.append(1, 'a'); 
}

2.6 减少循环内计算

将不变的表达式调用提到循环外(只执行一次)

// 优化前
for (int i = 0; i < vec.size(); ++i) {} // 每次调用size()(虽vector.size()是O(1),但仍有开销)
// 优化后
int n = vec.size();
for (int i = 0; i < n; ++i) {}

2.7 减少浮点运算

尽量避免浮点运算,浮点运算一般比整型慢。

三、内存管理

避免内存泄漏:使用智能指针,详细可参考之前文章:C++智能指针 解读_c++ 智能指针-CSDN博客

减少内存碎片std::vector使用连续内存,可减少碎片。

写在后面:以上是一些比较常见的C++性能优化技巧,读者可根据自身项目资源情况合理选择。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐