C++ 函数传参三种方式详解与 struct/class 核心区别
C++ 中的结构与类在语法形式上相似,但在默认访问权限和继承行为上存在关键差异;同时掌握值传递、引用传递和指针传递这三种函数调用方式,能有效避免数据意外修改并提升程序运行效率。
结构体基础与函数调用方式
结构体(struct)是一种用户自定义的数据类型,它既可以包含成员变量,也可以定义成员函数。在 C++ 中,对结构体成员的修改进程涉及不同的数据交换机制,直接决定了实参是否会被改变。
首先定义一个用于演示的结构体:
struct Student {
int number; // 成员变量:学号
char name[100]; // 成员变量:姓名
void num() { // 成员函数
number++;
}
};
第1步:理解传值调用(Value Passing)
目的:观察形参与实参是否共享内存空间,验证数据的独立性。
void func(Student temp) {
temp.number = 2000;
strcpy_s(temp.name, sizeof(temp.name), "lisi");
// 此时 temp 是 student 的副本,内存地址已发生改变当调用 func(student) 时,系统会创建一个临时的形参对象 temp,并将实参 student 的所有成员值拷贝给 temp。通过调试器可以观察到:student 的地址(如 0x00d7fd20)与函数内部 temp 的地址(如 0x00d7fbe4)完全不同。
调用前实参 student 的地址
进入函数后,形参 temp 拥有独立的地址
结论:由于进行了完整的内存内容拷贝,这种方式的效率较低,特别是当结构体体积较大时,开销显著。且在函数内修改 temp 不会影响外部的 student。
第2步:掌握引用调用(Reference Passing)
目的:利用别名机制,在不拷贝数据的情况下直接操作原对象,兼顾安全与效率。
void func1(Student &temp1) {
temp1.number = 2000;
strcpy_s(temp1.name, sizeof(temp1.name), "lisi");
// 形参 temp1 只是实参 student 的一个别名调用 func1(student) 时,不会创建新的副本。通过监视可以看到,函数内部的形参 temp1 与外部的实参 student 共享同一个内存地址(如均为 0x00d7fd20)。
调用前实参 student 的地址
函数内部形参 temp1 保持与实参一致
结论:C++ 推荐首选这种方式。它省略了数值拷贝过程,效率极高,且能直接修改外部对象的值。
第3步:分析指针调用(Pointer Passing)
目的:通过存储内存地址来传递对象,实现传统 C 语言风格的修改。
void func2(Student *temp2) {
temp2->number = 2000;
strcpy_s(temp2->name, sizeof(temp2->name), "lisi");
// 通过解引用来操作指向的目标调用时传入实参的地址 &student。函数接收的是该地址的值(如 0x003af858),并在内部通过箭头操作符修改其所指向的内容。
调用前实参 student 的地址
函数内部指针变量 temp2 记录目标地址
结论:虽然有效避免了拷贝,但由于需要处理指针运算和解引用,不如引用调用直观。在 C++ 开发习惯中,通常更倾向于使用引用。
权限修饰符与类的基本概念
“类”(class)同样为用户自定义数据类型,但其引入了严格的封装概念。理解访问控制是区分结构体与类的核心。
- public(公有):任何地方均可访问。通常作为对外提供功能的接口。
- private(私有):仅允许类/结构体内的成员函数访问。从外部无法直接获取或修改。
以教师信息为例,将敏感属性设为私有:
struct Teacher {
public:
int number;
char name[100];
void num() {
number++;
age = 30; // 内部成员函数可以合法访问私有变量
}
private:
int age; // 外界无法直接调用 teacher.age
};
int main2() {
Teacher teacher;
teacher.number = 1001; // OK: 公有成员可直接赋值
}
Struct 与 Class 的本质区别
虽然 class 和 struct 几乎可以实现相同的功能,但它们在两个关键维度上存在默认行为的不同。
1. 默认访问控制权限
这是两者最核心的差异:
- Struct:所有未明确指定修饰符的成员,默认访问级别为
public。
- Class:所有未明确指定修饰符的成员,默认访问级别为
private。
注意:如果在使用类或结构体时显式声明了所有的访问属性(即全部写明了 public: 或 private:),那么在这种特定情况下,两者的行为是一致的。
2. 默认继承方式
在进行面向对象编程的多重继承时,这也至关重要:
- Struct:默认采用
public继承,父类的public成员在子类中依然公开。
- Class:默认采用
private继承,父类的公共成员在子类中变为私有。
建议:为了降低维护难度,养成显式指定继承属性的习惯(如 class Child : public Parent)。
类的工程化组织与总结
在实际工程项目中,为了避免重复编译和维护混乱,应当遵循模块化标准。
文件分离规范:
- 头文件 (.h):存放类的定义、成员声明以及函数原型。例如
student.h,其中只包含数据结构和方法签名。 - 源文件 (.cpp):存放具体的函数实现逻辑。例如
student.cpp,通过引入对应的 .h 文件来编写函数体。
标准的头文件与源文件分离示意图
综上所述,C++ 提供了灵活的数据抽象手段。开发者应优先使用 class 并利用私有属性保护数据,在非必要不使用指针的场景下(尤其是大型对象传参时),充分利用引用传递的特性来提升效率与可读性。
以上就是 C++ 函数调用与 Struct 和 Class 区别的详细内容,更多关于 C++ 基础架构设计优化资料的关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









