值传递的缺点
值传递是指在函数调用中将参数的值复制到函数的形参中。虽然值传递在许多情况下是有效和方便的,但它也存在一些缺点,包括:
① 内存开销:值传递需要将参数的值复制到函数的形参中,这涉及到内存的分配和复制。对于大型对象或数据结构,复制操作可能会导致较大的内存开销和时间消耗。
② 性能影响:由于需要复制参数的值,值传递可能会对程序的性能产生影响。特别是当参数包含大量数据时,复制操作可能会导致函数调用的延迟和额外的计算开销。
③ 不适用于修改参数:值传递将参数的值复制到函数中,因此对形参所做的任何修改都不会影响到原始的参数。如果需要在函数内部修改参数的值,并希望这些修改对调用者可见,值传递就无法满足这个需求。
④ 对象切片问题:在面向对象编程中,如果使用值传递来传递派生类对象给基类参数,会发生对象切片问题。这意味着只会复制基类的部分数据,导致丢失派生类的特有成员和行为。
例如:对于包含大量数据的结构体,复制操作可能会导致较大的内存开销,并且对结构体的修改只在函数的局部范围内生效,无法影响到原始的结构体对象。
因此,当有有一个结构体数组时,有多人同时调用一个结构体函数时(以值传递的方式),就会造成巨额的开销。我们可以引入“地址传递的方式”。
地址传递
地址传递(传递指针或引用)是一种传递参数的方式,它可以解决值传递的一些限制并提供一些额外的优势。
通过地址传递,可以有效地操作和修改结构体对象,避免了复制和额外的内存开销。它还提供了更灵活的参数传递方式,使得函数能够直接访问和修改结构体的成员,并且在函数间共享同一个结构体对象。
结构体中const的应用场景
为了防止由于地址传递,造成在函数中修改了某些数据,防止用户的某些误操作,因此可以使用const,防止用户在函数中修改参数。
没有使用const前,可以在printStu2()中修改变量的值:
#include "iostream"
using namespace std;
//定义一个结构体类型
struct Student {
string name;
int age;
int sum_score;
};
void printStu2(Student *); //函数声明
int main() {
//创建一个结构体变量
Student s1 = {"张三", 25, 655};
printStu2(&s1);
cout << "主函数中" << endl << "姓名:" << s1.name << "\t年龄:" << s1.age << "\t分数:" << s1.sum_score << endl;
return 0;
}
//使用地址传递
void printStu2(Student *stu2) {
stu2->name = "李四";
stu2->age = 27;
stu2->sum_score = 356;
cout << "地址传递方式:" << endl << "姓名:" << stu2->name << "\t年龄:" << stu2->age << "\t分数:" << stu2->sum_score
<< endl;
}
使用const后: