掌握C++程序在执行过程中的内存分布,是开发高效且稳定应用程序的关键。通常情况下,一个正在运行的C++程序会将其内存划分为多个功能不同的区域:
该区域主要用于存放全局变量、静态变量以及常量数据。这些内容在程序启动阶段即被分配内存,并在整个程序生命周期内保持有效,直到程序终止才被统一释放。
栈由编译器自动进行管理,主要用于保存函数调用过程中的局部变量、参数值及返回地址等信息。其内存操作遵循“后进先出”的原则,具有极高的分配和回收效率。
堆区由开发者手动控制,通过特定操作符实现内存的动态申请与释放。
new
delete
nullptr
此区域用于存储程序编译后的机器码,一般为只读属性,以避免运行过程中被意外篡改,保障程序执行的安全性。
#include <iostream>
using namespace std;
int main(void)
{
// 动态申请可容纳10个整数的堆内存
int * arr = new int[10];
// 对数组元素赋初值
for (int i = 55; i < 65; i++)
arr[i - 55] = i;
// 遍历并输出所有数值
for (int i = 0; i < 10; i++)
cout << arr[i] << endl;
// 关键步骤:及时释放所申请的内存资源
delete[] arr;
return 0;
}
引用是C++提供的一种变量别名技术,允许为已有变量定义另一个名称,二者共享同一内存位置。
采用引用方式进行参数传递,既能避免值传递带来的复制开销,又比指针方式更加直观和安全。
#include <iostream>
using namespace std;
// 方法一:按值传递 —— 形参为实参的副本
void func1(int a, int b)
{
int temp = a;
a = b;
b = temp;
cout << "函数内交换后: a=" << a << ", b=" << b << endl;
}
// 方法二:按地址传递 —— 使用指针接收变量地址
void func2(int* a, int* b)
{
int temp = *a;
*a = *b;
*b = temp;
cout << "函数内交换后: a=" << *a << ", b=" << *b << endl;
}
// 方法三:按引用传递 —— 推荐做法,语法简洁且高效
void func3(int &a, int &b)
{
int temp = a;
a = b;
b = temp;
cout << "函数内交换后: a=" << a << ", b=" << b << endl;
}
int main(void)
{
int a = 10, b = 15;
cout << "原始值: a=" << a << ", b=" << b << endl;
// 值传递不影响原值
func1(a, b);
cout << "值传递后: a=" << a << ", b=" << b << endl;
// 指针传递可修改原始变量
func2(&a, &b);
cout << "地址传递后: a=" << a << ", b=" << b << endl;
// 恢复初始值
a = 10, b = 15;
// 引用传递效果同指针,但语法更清晰
func3(a, b);
cout << "引用传递后: a=" << a << ", b=" << b << endl;
return 0;
}
常量引用常用于函数形参设计中,既可防止内部误修改传入的数据,又能避免大对象拷贝带来的性能损耗。
void printValue(const int &value) {
// 函数体内只能读取 value,不能修改它
cout << "当前值为:" << value << endl;
}
3. 函数进阶特性
3.1 函数默认参数
在C++中,可以为函数的参数设置默认值,从而提升调用时的灵活性,并有效减少函数重载的数量。
示例代码如下:
#include <iostream>
using namespace std;
// 在函数声明中设定默认参数
int func1(int a = 10, int b = 15);
// 实现部分不能再重复指定默认值
int func1(int a, int b)
{
return a + b;
}
// 默认参数需从右往左连续定义
int func(int a, int b = 20, int c = 60)
{
return a + b + c;
}
int main(void)
{
// 调用时可省略部分或全部默认参数
cout << "func(29): " << func(29) << endl; // 结果:109
cout << "func(29, 30): " << func(29, 30) << endl; // 结果:119
cout << "func(29, 30, 40): " << func(29, 30, 40) << endl; // 结果:99
return 0;
}
new
注意事项说明:
- 默认参数必须从参数列表最右侧开始连续设置,不能跳跃。
- 默认值只能在函数声明或定义中出现一次,通常建议写在声明中。
- 可用常量、全局变量或函数返回值作为默认参数。
3.2 函数重载机制
函数重载允许在同一作用域内使用相同的函数名定义多个函数,只要它们的参数列表不同即可。这有助于提高代码的可读性与复用性。
3.2.1 构成函数重载的条件
- 多个函数位于同一作用域;
- 函数名称完全相同;
- 参数列表在类型、数量或顺序上存在差异。
3.2.2 使用时的关键注意点
- 仅返回类型不同不足以构成重载;
- 引用类型(如 int&)可作为区分重载的依据之一;
- 若使用了默认参数,可能引发调用歧义,应避免模糊匹配。
4. 类和对象:面向对象编程的基础
C++支持三大核心特性:封装、继承与多态。其中,封装是实现数据抽象和模块化设计的根本手段。
4.1 封装的核心意义与实现方式
4.1.1 属性与行为的统一建模
封装的本质是将数据(属性)与其相关的操作方法(行为)组合成一个独立单元——即“类”。
例如定义一个圆形类:
#include <iostream>
using namespace std;
const double PI = 3.14159;
class Circle
{
public:
int m_r; // 半径属性
// 成员函数:计算周长
double getcalZc()
{
return 2 * PI * m_r;
}
};
int main(void)
{
Circle my_circle;
my_circle.m_r = 5;
cout << "半径为" << my_circle.m_r << "的圆周长: "
<< my_circle.getcalZc() << endl;
return 0;
}
delete
该示例展示了如何将圆的半径和计算周长的方法封装在一个类中,形成逻辑上的整体。
4.1.2 访问权限控制机制
封装的重要组成部分是对成员访问级别的管理。C++提供了三种访问控制符:
- public:公共成员,既可在类内部访问,也可在外部直接调用;
- protected:受保护成员,允许在本类及派生类中访问;
- private:私有成员,仅限于类内部访问,外部不可直接操作。
学生信息管理类实例:
#include <iostream>
using namespace std;
class StudentInfo
{
private:
string m_name; // 姓名(私有)
string m_Num; // 学号(私有)
public:
// 设置信息接口
void setstudentinfo(string name, string num)
{
m_name = name;
m_Num = num;
}
// 输出信息接口
void getstudentinfo()
{
cout << "姓名: " << m_name << " | 学号: " << m_Num << endl;
}
};
int main(void)
{
StudentInfo mystudent;
mystudent.setstudentinfo("张三", "19577532");
mystudent.getstudentinfo();
return 0;
}
nullptr
通过私有化数据并提供公共接口进行访问,实现了数据的安全性和隐藏性。
4.1.3 struct 与 class 的主要区别
在C++中,struct 和 class 都可用于定义类类型,其语法功能几乎一致,唯一的默认差异在于访问权限:
- struct 的默认访问权限为 public;
- class 的默认访问权限为 private。
因此,在不需要特别强调访问控制的情况下,struct 更适合用于简单的数据聚合;而 class 更适用于需要严格封装的复杂对象设计。
在C++中,class与struct的默认访问权限存在明显差异: - class成员默认为private,外部无法直接访问; - struct成员默认为public,允许外部直接读写。 例如以下代码展示了这一特性:
#include <iostream>
using namespace std;
class MyClass
{
string m_name; // 默认为private
string m_Num;
};
struct MyStruct
{
string m_name; // 默认为public
string m_Num;
};
int main(void)
{
MyClass C1;
MyStruct C2;
// 合法访问:struct成员默认public
cout << C2.m_name << endl;
// 非法访问:class成员默认private
// cout << C1.m_name << endl;
return 0;
}
将成员属性设置为私有(private)并提供公共接口进行访问,是面向对象编程中的重要实践。这种设计方式具有多个优势: 1. 可以精确控制属性的读写权限,实现只读、只写或可读可写。 2. 在设置值时加入数据验证逻辑,确保数据的有效性和合理性。 3. 隐藏内部实现细节,提升代码的安全性与维护性。 以下Person类示例演示了如何通过公有方法安全地操作私有成员:new
#include <iostream>
using namespace std;
class Person
{
private:
string m_name; // 私有属性,外部无法直接访问
string m_sex;
public:
// 设置姓名,并进行非空校验
void setname(string name)
{
if (!name.empty()) {
m_name = name;
} else {
cout << "姓名不能为空!" << endl;
}
}
// 获取姓名信息(只读访问)
void getname()
{
cout << "姓名: " << m_name << endl;
}
};
int main(void)
{
Person person1;
person1.setname("王明");
person1.getname();
return 0;
}
下面是一个更复杂的应用实例——立方体类(Cube)的设计。该类使用嵌套结构体组织内部数据,并封装了多种操作功能: - 尺寸设置与合法性检查 - 获取当前尺寸 - 计算表面积和体积 - 比较两个立方体是否相等 完整实现如下:delete
#include <iostream>
using namespace std;
class Cube
{
private:
// 使用嵌套结构体管理立方体的几何参数
struct CubeInfo
{
int m_L; // 长
int m_W; // 宽
int m_H; // 高
} m_CubeInfo;
public:
// 设置立方体长宽高,要求均为正数
void setDimensions(int length, int width, int height)
{
if (length > 0 && width > 0 && height > 0) {
m_CubeInfo.m_L = length;
m_CubeInfo.m_W = width;
m_CubeInfo.m_H = height;
} else {
cout << "尺寸必须为正数!" << endl;
}
}
// 输出当前立方体的尺寸信息
void getDimensions()
{
cout << "长: " << m_CubeInfo.m_L
<< ", 宽: " << m_CubeInfo.m_W
<< ", 高: " << m_CubeInfo.m_H << endl;
}
// 计算并打印表面积
void calculateSurfaceArea()
{
int area = 2 * (m_CubeInfo.m_L * m_CubeInfo.m_W +
m_CubeInfo.m_L * m_CubeInfo.m_H +
m_CubeInfo.m_W * m_CubeInfo.m_H);
cout << "表面积: " << area << endl;
}
// 计算并打印体积
void calculateVolume()
{
int volume = m_CubeInfo.m_L * m_CubeInfo.m_W * m_CubeInfo.m_H;
cout << "体积: " << volume << endl;
}
// 判断当前立方体是否与另一个立方体完全相同
bool isEqual(const Cube& other)
{
return (m_CubeInfo.m_L == other.m_CubeInfo.m_L &&
m_CubeInfo.m_W == other.m_CubeInfo.m_W &&
m_CubeInfo.m_H == other.m_CubeInfo.m_H);
}
};
nullptr
int main(void)
{
Cube cube1, cube2;
// 设置第一个立方体的尺寸
cube1.setDimensions(2, 3, 4);
cout << "立方体1信息:" << endl;
cube1.getDimensions();
cube1.calculateSurfaceArea();
cube1.calculateVolume();
// 配置第二个立方体的参数
cube2.setDimensions(2, 3, 4);
cout << "\n立方体2信息:" << endl;
cube2.getDimensions();
// 对比两个立方体是否一致
if (cube1.isEqual(cube2)) {
cout << "两个立方体相等" << endl;
} else {
cout << "两个立方体不相等" << endl;
}
return 0;
}
#include <iostream>
using namespace std;
class Person
{
public:
// 默认构造函数
Person();
// 接收姓名参数的构造函数
Person(string name);
// 析构函数声明
~Person();
private:
string m_name;
};
// 实现默认构造函数
Person::Person()
{
cout << "默认构造函数被调用" << endl;
m_name = "未知";
}
// 实现带参构造函数
Person::Person(string name)
{
cout << "带参数的构造函数被调用" << endl;
m_name = name;
}
// 析构函数实现
Person::~Person()
{
cout << m_name << "的析构函数被调用" << endl;
}
int main(void)
{
cout << "创建对象person1:" << endl;
Person person1; // 触发默认构造
cout << "\n创建对象person2:" << endl;
Person person2("张三"); // 调用有参构造
cout << "\n程序结束,开始清理对象..." << endl;
// 析构调用顺序遵循后进先出原则
return 0;
}
#include <iostream>
#include <string>
using namespace std;
class Person
{
string m_name; // 姓名
int m_age; // 年龄
char m_sex; // 性别
public:
// 默认构造函数
Person();
// 带参构造函数,采用初始化列表方式
Person(string name, int age, char sex);
// 析构函数
~Person();
void display() {
cout << "姓名: " << m_name
<< ", 年龄: " << m_age
<< ", 性别: " << m_sex << endl;
}
};
// 使用初始化列表完成默认值设定
Person::Person() : m_name("未知"), m_age(0), m_sex('U')
{
cout << "默认构造函数被调用" << endl;
}
// 利用初始化列表传递外部参数
Person::Person(string name, int age, char sex)
: m_name(name), m_age(age), m_sex(sex) // 初始化段
{
cout << "带参数的构造函数被调用" << endl;
}
// 析构函数实现
Person::~Person()
{
cout << "析构函数被调用 - ";
display();
}
new
int main(void)
{
// 调用默认构造函数创建对象
delete
#include <iostream>
using namespace std;
class Screen
{
public:
// 构造函数的多种重载形式
Screen(); // 默认构造函数
Screen(int height, int width);
Screen(int height, int width, string content);
~Screen();
private:
int m_height;
int m_width;
string m_content;
};
// 默认构造函数实现
Screen::Screen() : m_height(0), m_width(0), m_content("")
{
cout << "默认构造函数被调用" << endl;
}
// 包含高度与宽度参数的构造函数
Screen::Screen(int height, int width)
: m_height(height), m_width(width), m_content("")
{
cout << "构造函数被调用 - 高度: " << height
<< ", 宽度: " << width << endl;
}
// 三参数构造函数:高度、宽度及显示内容
Screen::Screen(int height, int width, string content)
: m_height(height), m_width(width), m_content(content)
{
cout << "构造函数被调用 - 高度: " << height
<< ", 宽度: " << width << endl;
cout << "显示内容: " << content << endl;
}
// 析构函数,在对象销毁时自动调用
Screen::~Screen()
{
cout << "析构函数被调用 - 屏幕对象被销毁" << endl;
}
int main(void)
{
cout << "创建screen1对象:" << endl;
Screen screen1(10, 20, "Hello, World!");
cout << "\n创建screen2对象:" << endl;
Screen screen2(15, 25);
cout << "\n创建screen3对象:" << endl;
Screen screen3;
return 0;
}
new
本文全面讲解了C++编程中的关键基础概念,涵盖内存模型的理解、引用机制的应用,以及面向对象编程中类与对象的封装原理。这些内容构成了掌握C++高级功能的重要前提。
delete
// 示例:使用带参数的构造函数创建对象
Person person2("李四", 25, 'M');
person2.display();
cout << endl;
// 调用无参对象并展示信息
Person person1;
person1.display();
cout << endl;
return 0;
扫码加好友,拉您进群



收藏
