C++ 类的传值 和 传引用

C++ 类 传值 和 传引用 的区别

传参时通过 值传递引用传递 类变量的区别,以及临时变量 直接赋值引用赋值 的区别。

使用引用的方法可以减少拷贝构造函数的调用次数,节省内存资源。

测试代码:

#include <iostream>
using namespace std;

class A{
    
    
public:
	int val;
	A(){
    
    
		cout << "默认构造函数" << endl;
	}

	A(int v) : val(v){
    
    
		cout << "重载构造函数" << endl;
	}

	A(A& b){
    
    
		val = b.val;
		cout << "拷贝构造函数" << endl;
	}
};

void fun1(A a){
    
    
	cout << "fun1 -- 值传递 -- 临时变量未用引用 &" << endl;
	cout << "a address: " << &a << endl;
	A b = a;
	cout << "b address: " << &b << endl;
	b.val = 1;
	cout << b.val << endl;
}

void fun2(A a){
    
    
	cout << "fun2 -- 值传递 -- 临时变量使用引用 &" << endl;
	cout << "a address: " << &a << endl;
	A& b = a;
	cout << "b address: " << &b << endl;
	b.val = 2;
	cout << b.val << endl;
}

void fun3(A& a){
    
    
	cout << "fun3 -- 引用传递 -- 临时变量未用引用 &" << endl;
	cout << "a address: " << &a << endl;
	A b = a;
	cout << "b address: " << &b << endl;
	b.val = 3;
	cout << b.val << endl;
}

void fun4(A& a){
    
    
	cout << "fun4 -- 引用传递 -- 临时变量使用引用 &" << endl;
	cout << "a address: " << &a << endl;
	A& b = a;
	cout << "b address: " << &b << endl;
	b.val = 4;
	cout << b.val << endl;
}

int main()
{
    
    
	A test(0);
	cout << "test address: " << &test << endl << endl;

	fun1(test);
	cout << "test.val = " << test.val << endl << endl;

	fun2(test);
	cout << "test.val = " << test.val << endl << endl;

	fun3(test);
	cout << "test.val = " << test.val << endl << endl;

	fun4(test);
	cout << "test.val = " << test.val << endl << endl;
 	return 0;
}

输出:

重载构造函数
test address: 0x61ff04

拷贝构造函数
fun1 -- 值传递 -- 临时变量未用引用 &
a address: 0x61ff08
拷贝构造函数
b address: 0x61fedc
1
test.val = 0

拷贝构造函数
fun2 -- 值传递 -- 临时变量使用引用 &
a address: 0x61ff0c
b address: 0x61ff0c
2
test.val = 0

fun3 -- 引用传递 -- 临时变量未用引用 &
a address: 0x61ff04
拷贝构造函数
b address: 0x61fedc
3
test.val = 0

fun4 -- 引用传递 -- 临时变量使用引用 &
a address: 0x61ff04
b address: 0x61ff04
4
test.val = 4

总结:

函数中对类进行值传递时,会先利用拷贝构造函数创建一个与传入参数相同的临时类变量,类似于执行了 A a(test)
然后通过直接赋值 A b = a; 再进行一次拷贝构造函数,创建一个新的类变量b。

引用传递,则是直接传入参数的地址,减少了一次拷贝构造函数的调用;
同样的,引用赋值也未创建新的类变量,而是直接通过参数地址进行操作。

通过 引用传递参数 和 引用赋值,类似于浅拷贝,都未创建新的类变量,因此在函数中对值的改变将会传递到原变量中。

如果不想让函数修改参数的值,只要把参数声明为 const 常量即可。

void fun4(const A& a){
    
    
	const A& b = a;
	cout << b.val << endl;
}

因此,对于 string、vector 等其他类的传递和调用时,可以通过引用传递的方法减少内存的拷贝

猜你喜欢

转载自blog.csdn.net/qq_19887221/article/details/125977320