指针和引用作为返回值

本文详细介绍了C++中函数返回值的处理方式,包括不同大小返回值的处理,临时量的生成时机,以及引用的使用条件。同时讨论了函数传参的三种方式:传值、传地址和传引用,分析了各自的优缺点。最后,探讨了普通类型、指针和引用作为返回值的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


一、 函数返回值
     1.如果返回值小于4byte 用寄存器eax带回返回值
     2.如果返回值大于4byte小于8btye,用两个寄存器eax edx带回返回值
     3.如果返回值大于8byte,在调用前main函数中产生临时量接受返回值
 二、临时量生成的三种情况
     1.函数调用之前产生,目的是为了接受函数的返回值
     2.函数的return语句处
     3.函数调用之后
 三、引用的条件
     1.必须进行初始化
     2.必须能取地址
     内置类型产生的临时量都是常量 通过eax edx带回 不能修改
     自定义类型产生的临时量是变量 可以进行修改

四、函数传参

1.传值

    函数调用过程会产生一个临时变量用形参的形式代替,
    最终把实参得值传给新分配的临时变量,这种传值避免了
    函数恶意修改所传的值;

2.传地址
   传地址坏处就是不能控制该值被程序恶意修改
        好处就是如果程序需要改变这个值 那么就可以改变 无束缚

3.传引用
传引用并没有引用新的变量 只是给已存在的变量起了一个别名
编译器不会为这个别名开辟内存空间 这个引用和引用的变量使用同一内存空间

五、普通类型作为返回值

//函数返回值为普通类型的返回值接收情况
int GetInt()
{
	int value = 10;
	return value;
}


int main ()
{
	//int &a = GetInt(); //error 函数返回值大小为4byte 由寄存器eax带回 对立即数不能取地址 
	                      //引用的条件 :必须进行初始化  必须能取地址
	//int a = GetInt();// OK //用一个与函数返回值同类型的变量接收
	//int *a= &GetInt(); //error 函数的返回值是一个立即数 不能取地址

	/*使用常引用接收返回值的实质有两步
	  1.在调用GetInt函数后产生一个常临时量
	       const int tmp =  GetInt();
	  2.然后在main函数的常引用 引用这个临时量 从而接收到返回值
	       const int &a = tmp;
	 */
	const int &a = GetInt();//error a引用的是一个常临时量的地址
	
	cout<<"a = "<<a<<endl;
	return 0;
}

六、指针作为返回值的情况

//函数返回值为指针的返回值接收情况
int*  GetIntPtr()
{
	static int value = 10;//数据存放在.data段
	return &value;
	//lea eax [value]
	//将return之后的内容的地址通过eax带回
}


int main()
{
	//int *p = &GetIntPtr();//error 返回值等于4byte字节 由eax带回 对立即数不能取地址
	//int *&p = GetIntPtr();//error 指针引用 由于函数返回值有eax带回 不能对立即数取地址
	
	/*使用常引用接收返回值的实质有两步
	  1.在GetIntPtr()函数调用之后产生常临时量接收返回值
	    int *const tmp = GetIntPtr();
      2.然后在main函数的常引用 引用这个常临时量 从而接收到返回值
	       int *const &a = tmp;
	*/
   //	int *const &p = GetIntPtr();// 0K
	//int a = *GetIntPtr();// OK 后面返回指针在解引用 是一个具体的值  可以用a接收
	//int &a = *GetIntPtr(); //OK a引用的是解引用之后的变量的内存 类似于下面的例子
	/*
	 int a = 10;
	 int *p = &a;
	 int &b = *p;//成立  b引用的是p所指向的a那块内存 而不是a里的内容 
	 所以上述的int &a = *GetIntPtr();成立 
	*/
	cout<<a<<endl;
	return 0;
}

七、引用作为返回值

int&  GetIntRef()
{
	static int value = 10;//数据存放在.data段
	return value;
	//lea eax [value]
	//将return之后的内容的地址通过eax带回
}


int main()
{
	//int p = GetIntRef();// OK 会对eax带回的地址进行解引用 将值赋给p  p = *eax
	//int *p = &GetIntRef(); // OK eax直接带回的就是地址 所以指针p可以指向这片空间  int *p = &value;
	int &p = GetIntRef(); //OK p引用eax带回来的地址 级int &p = &value;

}

 

### C++ 中返回引用指针的区别、使用场景及最佳实践 #### 返回引用的情况 当函数返回一个引用时,实际上是在返回对象的一个别名。这意味着调用者可以修改原始数据而不仅仅是其副本。这种方式常用于实现操作符重载以及提供对类成员变量的安全访问。 对于返回引用而言,在设计上需要注意的是确保被引用的对象在其生命周期内有效存在[^1]。如果返回局部对象的引用,则可能导致悬空引用的风险,进而引发未定义行为。 ```cpp class MyClass { public: int& getValRef() { return value_; } private: int value_; }; ``` #### 返回指针的情形 相比之下,通过指针来传递或返回数据提供了更大的灵活性。然而这也伴随着额外的责任——管理内存分配释放。特别是裸指针(raw pointer),容易造成资源泄漏等问题。因此推荐尽可能采用智能指针代替传统意义上的手动管理指针[^4]。 - **返回普通指针**:适用于需要表示可选值的情况下;但是应当谨慎处理所有权问题。 - **返回`nullptr`**:作为一种特殊标记表明不存在有效的目标实体。 ```cpp Widget* findWidget(const std::string& name) { auto it = widgets.find(name); if (it != widgets.end()) { return &(it->second); } else { return nullptr; } } ``` #### 使用场景对比 | 特性 | 引用 | 指针 | | --- | --- | --- | | 是否允许为空 | 否 | 是 | | 对象生存期依赖关系 | 被引用对象必须存活于整个作用域期间 | 可以独立控制指向对象的生命期 | #### 最佳实践建议 - 避免不必要的拷贝开销,优先考虑返回引用而非复制大对象; - 当确实有必要返回动态创建的对象时,应首选智能指针如 `std::unique_ptr` 或 `std::shared_ptr` 来自动管理资源回收过程[^3]; - 如果只是简单地读取某个内部状态而不改变它的话,那么应该返回 const 类型的引用以防止意外更改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值