关于函数返回值中的const以及引用的用法

本文解析了C++中函数返回值的设计原理,探讨了赋值运算符重载为何需返回引用,常量返回值如何避免误用,以及不同场景下为何选择返回引用或常量引用。

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

最近在复习C++的时候遇到了一些比较容易混淆的概念,其中就包括函数返回值的问题。让我们看一下下面这几个函数:

class CMyString {...};
CMyString& CMystring::operator =(const CMyString &str);//函数①

class Rational {...};
const Rational Rational::operator* (const Rational& lhs, const Rational& rhs);//函数②
//函数②
class TextBlock {
public:
    ...
    const char& operator[](std::size_t position) const
    { return text[position]; }//函数③
    char& operator[](std::size_t position)
    { return text[position]; }//函数④
private:
    std::string text;
};

关于函数①:
作为赋值运算符的重载,如果返回值不是reference to CMyString 而是CMyString,那会产生什么结果?假设有三个CMyString的实例,那么该语句:

str1 = str2 = str3;

就无法通过编译。
因为,如果函数的返回类型是个内置类型,那么改动函数返回值从来就不合法。纵使合法,C++以by value返回对象这一事实意味被改动的其实是str1 = str2的一个副本,不是str1 = str2自身,这不是我们想要的结果。
同样的理由也可以解释函数③及函数④为什么要返回一个引用,不然的话

TextBlock tb("Hello");
tb[0] = 'x';

第二句赋值语句也是不合法的。

关于函数②:
将返回值设为const则相反,是为了避免有人“无意识地赋值”。比如说接下来这个例子:

Rational a, b, b;
...
(a * b) = c;    // 在a * b的成果上调用operator=

这种诡异的情况多发生在:

if (a * b = c) ...  //应该每个人都这么干过

所以为了避免这种情况,能使用const的时候尽量使用const。

函数③:
有同学应该就会问了,函数①返回引用是为了二次赋值,函数②返回const是为了避免二次赋值,那函数③返回const的引用又是什么鬼?!
这里就涉及另一种情况了,即对const对象的操作
请看以下代码:

class object{
public:
    char getMember{ return p };
private:
    char p;
};

void test(const object & parm){
    char temp = parm.getMember();
}
// 编译错误,error C2662: 'object::getMember' : cannot convert 'this' pointer from 'const object' to 'object &'

原因在于函数的参数是一个pass by reference-to-const(插一句,这是一个广泛使用的技术,首先这样避免了调用复制构造函数,提高了效率、其次避免了参数被莫名其妙地修改),而只有const成员函数可以作用于const对象。

函数④:
函数④就很好理解了,即对non-const对象进行操作。同样函数④也需要考虑被赋值的情况,所以需要返回一个引用。函数③和函数④可以用下面这一段代码来加深理解:

TextBlock tb("Hello");
std::cout << tb[0];     //调用 non-const TextBlock::operator[]

const TextBlock ctb("World");//调用const TextBlock::operator[]
std::cout<< ctb[0];

本篇博客的例子及知识点来自《Effective C++》以及《剑指Offer》,如有不完善的地方还请联系我,多谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值