C++ 函数参数传递与对象返回探究

1 函数参数对象值传递:

#include<iostream>
using namespace std;
class Demo
{
public:
	int x;
	Demo(int x)
	{
		this->x = x;
	}
};

Demo operator+(Demo a,Demo b)
{
	cout << "operator内a、b地址:" << &a << " " << &b << endl;
	Demo c(a.x + b.x);
	cout << "operator内c地址:" << &c << endl;
	return c;
}

int main()
{
	Demo a(1), b(2);
	cout << "main内a、b地址:" << &a << " " << &b << endl;
	cout << "main内c地址:" << &(a+b) << endl;
	system("pause");
	return 0;
}

在这里插入图片描述
可见对象传递过去会被拷贝。

2 函数参数对象引用传递

修改+号重载函数:

Demo operator+(Demo &a,Demo &b)
{
	cout << "operator内a、b地址:" << &a << " " << &b << endl;
	Demo c(a.x + b.x);
	cout << "operator内c地址:" << &c << endl;
	return c;
}

在这里插入图片描述
可见函数参数引用传递不需要拷贝新对象。

3 返回对象值

从上面结果可以看出,是拷贝,因为局部变量c出了函数域就会被销毁,因此在函数域外是函数域内的c的拷贝。

4 返回对象的引用

修改+号重载函数为:

Demo& operator+(Demo &a,Demo &b)
{
	cout << "operator内a、b地址:" << &a << " " << &b << endl;
	Demo c(a.x + b.x);
	cout << "operator内c地址:" << &c << endl;
	return c;
}

在这里插入图片描述
可以看出在+号重载函数与调用函数main内两个的c是同一个地址的,但是问题是回到main函数时,该地址的内存已经被销毁了,将main函数改为下面的形式进行验证:

int main()
{
	Demo a(1), b(2);
	cout << "main内a、b地址:" << &a << " " << &b << endl;
	Demo& c = a + b;
	cout << "main内c地址:" << &c << " 值:" << c.x << endl;
	system("pause");
	return 0;
}

在这里插入图片描述
结果可见,该内存并没有被销毁,不知道是不是VS的返回值优化“return value optimization"在起作用。

5 const作用

理想的重载函数应该为:

const Demo operator+(const Demo &a,const Demo &b)
{
	return Demo(a.x + b.x);//不出现局部/临时变量名c,给予编译器最大权限去优化
}

第一个const修饰函数是为了防止不符合使用习惯的下式出现:

( a + b) = c;

如果没有const修饰函数,a+b会返回一个Demo的临时/局部变量,可以再被c赋值,但是这不符合我们的使用习惯,而且给一个临时/局部变量赋值一般情况下也没有意义。
后面参数的两个const是为了防止调用函数改变引用的变量,即给予引用变量a、b只读属性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当我们将函数作为参数传递给另一个函数时,我们可以使用函数指针或函数对象函数器)来实现。 1. 函数指针: 使用函数指针,我们首先需要定义一个与要传递函数具有相同签名(参数返回值类型)的函数指针类型。然后,我们可以将函数的名称赋给指针,并将该指针作为参数传递给另一个函数。 例如,假设我们有一个函数 `void foo(int)`,我们希望将其作为参数传递给另一个函数 `void bar(void (*func)(int))`,则可以这样做: ```cpp void foo(int x) { // 函数体 } void bar(void (*func)(int)) { // 调用函数指针所指向的函数 func(42); } int main() { // 将函数指针作为参数传递给另一个函数 bar(foo); return 0; } ``` 2. 函数对象函数器): C++中的函数对象是可调用对象,可以像函数一样被调用。我们可以定义一个类,并在该类中实现 `operator()` 运算符重载。然后,我们可以创建该类的对象,并将该对象作为参数传递给另一个函数。 例如,假设我们有一个函数对象类 `Foo`,我们希望将其作为参数传递给另一个函数 `void bar(Foo)`,则可以这样做: ```cpp class Foo { public: void operator()(int x) { // 函数体 } }; void bar(Foo func) { // 调用函数对象 func(42); } int main() { // 将函数对象作为参数传递给另一个函数 Foo foo; bar(foo); return 0; } ``` 无论是使用函数指针还是函数对象,我们都可以将函数作为参数传递给其他函数,并在接受参数函数中调用该函数。这样可以实现更灵活的代码设计和功能扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值