通常情况下,编码规范中要求如下:

  1. 所有的成员变量都要被设置为private
  2. 对外开放的接口(函数),设置为public
  3. 不需要对外开放的接口(函数),设置为private或protected
  4. 如果在类的外部想要访问成员变量,那么可以在类中声明public的函数进行间接访问
  5. 一般情况下,公有函数声明在类的最开始位置,其后是protected、private函数,最后是成员变量
  6. 通常同访问权限的函数和变量会分开书写。(增强代码逻辑,更清晰)
  7. 在类的声明中通常不出现函数定义,函数定义通常都在类的外部实现
  8. 类声明一般放在.h文件中,类成员函数的定义通常放在.cpp中

一,引用

1.引用的概念:引用是变量的别名。一旦引用和某个变量绑定,就相当于给这个变量起了另一个名字。

使用引用时的注意:

  • 引用必须在定义时初始化,不允许空引用
  • 引用一旦初始化,就不能再引用其它数据
  • 引用实际上就是一块内存的别名

2.引用的主要功能:传递函数的参数 返回函数的值。

3.C++中常用的方式有三种:值传递,指针传递和引用传递

引用传递的性质像指针传递,书写形式像值传递

引用与指针的区别:

  • 指针是一个地址,引用是一个别名
  • 指针的值可以为空,但是引用的值不能为NULL
  • 非const指针可以改变指向,引用不可以
  • sizeof引用得到的是变量本身的大小,而指针是4个字节(32位操作系统中)
  • 指针和引用在函数传参时也不一样

4.引用的用途

(1)函数参数传递

避免实参拷贝,提高效率,还能在函数中修改实参。

void swap(int& x, int& y) {
    int temp = x;
    x = y;
    y = temp;
}

int main() {
    int a = 1, b = 2;
    swap(a, b);
    cout << "a=" << a << ", b=" << b << endl; // a=2, b=1
}

(2)函数返回值

可以返回引用,让调用者直接操作函数内部的数据

int& getElement(int arr[], int index) {
    return arr[index]; // 返回数组元素的引用
}

int main() {
    int nums[3] = {10, 20, 30};
    getElement(nums, 1) = 200; // 修改第二个元素
    cout << nums[1] << endl;   // 输出 200
}

(3)常量引用

既能避免拷贝,又能保证函数中不能修改传入参数。常用于传递大对象。

void print(const string& s) {
    cout << s << endl;
}

int main() {
    string str = "Hello C++";
    print(str);  // 高效传参,不会拷贝字符串
}

引用示例程序:

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

// 1. 使用引用作为函数参数
void swapValues(int& x, int& y) {
    int temp = x;
    x = y;
    y = temp;
}

// 2. 使用常量引用
void printMessage(const string& msg) {
    cout << "打印信息: " << msg << endl;
}

// 3. 使用引用作为返回值(返回数组元素的引用)
int& getElement(int arr[], int index) {
    return arr[index]; // 返回引用,可以修改原数组
}

int main() {
    // 引用的基本用法
    int a = 10;
    int& ref = a;  // ref 是 a 的别名
    ref = 20;      // 改 ref 就是改 a
    cout << "1. 引用修改变量: a = " << a << endl;

    // 函数参数中的引用
    int x = 5, y = 8;
    swapValues(x, y);
    cout << "2. 交换后: x = " << x << ", y = " << y << endl;

    // 常量引用
    string str = "Hello C++ 引用";
    printMessage(str);

    // 返回引用
    int arr[3] = {1, 2, 3};
    getElement(arr, 1) = 200;   // 修改数组的第二个元素
    cout << "3. 数组修改后 arr[1] = " << arr[1] << endl;

    return 0;
}

运行结果:

二,堆内存管理

什么是堆内存?

栈内存:由编译器自动分配和释放(局部变量、函数参数等),生命周期由作用域决定。

堆内存:程序运行时向操作系统申请的一块内存,由程序员手动管理,直到 delete 或 free 才释放。

全局/静态存储区:存放全局变量和静态变量,由系统在程序运行期间自动管理。

C++ 中堆内存的申请与释放

C++ 提供了两套机制:

(1)  C 风格:malloc/free

#include <cstdlib>int* p = (int*)malloc(sizeof(int) * 10); // 申请10个int空间
free(p); // 释放

malloc 返回 void*,需要强制类型转换。

不会调用对象的构造函数 / 析构函数。

示例程序:

#include <iostream>
#include <cstdlib>   // malloc, free
using namespace std;

int main() {
    // 申请10个 int 空间
    int* arr = (int*)malloc(sizeof(int) * 10);
    if (!arr) {
        cout << "malloc failed!" << endl;
        return -1;
    }

    // 初始化并输出
    for (int i = 0; i < 10; i++) {
        arr[i] = i * 10;
        cout << arr[i] << " ";
    }
    cout << endl;

    // 释放内存
    free(arr);

    return 0;
}

(2)  C++ 风格:new/delete

int* p1 = new int;       // 分配一个int

*p1 = 100;delete p1;               // 释放

int* p2 = new int[10];   // 分配数组delete[] p2;             // 释放数组

new 返回的是指定类型的指针,不需要强转。

会调用对象的构造函数。

delete 会调用析构函数。

注意:数组必须用 delete[] 释放。

示例程序:

#include <iostream>
using namespace std;

int main() {
    // 申请单个 int
    int* p = new int;
    *p = 100;
    cout << "单个 int: " << *p << endl;
    delete p;  // 释放

    // 申请 int 数组
    int* arr = new int[5];
    for (int i = 0; i < 5; i++) {
        arr[i] = i + 1;
        cout << arr[i] << endl;
    }
    delete[] arr; //必须用 delete[] 释放

    return 0;
}

new/delete不仅可以分配内存,还可以自动调用对象的构造函数和析构函数,因此对于类对象而言,最好使用new/delete来管理

new与delete的区别

相同点:都可以从堆区获取内存
不同点:

1.实现方式

malloc / free:库函数(C 语言风格),本质是函数调用 → 有函数调用开销。

new / delete:C++ 关键字,由编译器直接处理 → 没有函数调用开销。

2.内存大小

malloc:必须手动指定字节大小,例如:

long* p = (long*)malloc(10 * sizeof(long));

new:编译器会根据类型自动计算大小,例如:

long* p = new long[10];

3.对象构造/析构

malloc/free:只分配和释放内存,不会调用对象的构造函数或析构函数。

new/delete:在分配内存时会调用构造函数,在释放内存时会调用析构函数。

4.返回类型

malloc:返回 void*,需要强制类型转换。

new:返回的是对应类型的指针,不需要强转。

5.异常处理

malloc:分配失败时返回 NULL。

new:分配失败时会抛出 std::bad_alloc 异常(除非使用 new(std::nothrow))。

总结:

malloc/free 只是单纯的内存管理函数(C 语言风格)。

new/delete 是 面向对象的内存管理工具,同时管理内存和对象的生命周期。

常见问题:

内存泄漏
  申请了堆内存却没有释放。
   解决:及时 delete,推荐使用智能指针。

 野指针 / 悬空指针
指针未初始化、或内存释放后继续使用。
解决:初始化指针;释放后置为 nullptr。

 重复释放
同一块内存 delete 两次,导致程序崩溃。

Logo

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

更多推荐