const参数,const返回值与const函数 .

include <iostream>
2 #include <string>
3 using namespace std;
4
5 class person
6 {
7 private:
8     int id;
9     string name;
10 public:
11     person(int id, string name):id(id), name(name)
12     {
13         cout << “invoke con” << endl;
14     }
15     void show();
16     ~person()
17     {
18         cout << “invoke decon ~” << endl;
19     }
20     string get_name()const
21     {
22         return name;
23     }
24     void set_name(string n)
25     {
26         name = n;
27     }
28
29 };
30
31 void person::show()
32 {
33     cout << “id: ” << id << ” name: ” << name << endl;
34 }
35
36 string format(person *ps)
37 {
38     return “[" + ps->get_name() + "]“;
39 }
40
41 string format(const person &ps)
42 {
43     //成员函数get_name定义时如果没有末尾的const,将不能在此处调用。因为ps是const的引用
44 //    ps.set_name(“m”);
45     return “&” + ps.get_name() + “&”;
46 }
47
48 int main(void)
49 {
50     person p(1, “a”);
51     p.show();
52
53     cout << “format: ” << format(&p) << endl;
55     cout << “format&: ” << format(p) << endl;
56
57
58     return 0;
59 }
1. const在函数返回值前:
返回const值,意思指返回的原函数里的变量的初值不能被修改,但是函数
按值返回的这个变量被制成副本,能不能被修改就没有了意义,它可以被赋给任何
的const或非const类型变量,完全不需要加上这个const关键字.但这只对于内部
类型而言(因为内部类型返回的肯定是一个值,而不会返回一个变量,不会作为左
值使用),对于用户自定义类型,返回值是常量是非常重要的,
X Fuction1 () { return X(); }
const X Fuction2 () { return X(); }
如有上面的自定义类X,和函数Fuction1()和Fuction2(),我们进行如下操作时:
Fuction1()=X(1); //没有问题,可以作为左值调用
Fuction2()=X(1); //编译错误,const返回值禁止作为左值调用.因为左值
把返回值作为变量会修改其返回值,const声明禁止这种修改。
返回的类型为const型不能被修改
对于int来说没有什么意义 返回值只能为右值本身就是const
2. const在函数末尾:
const 成员函数
任何不会修改数据成员的函数都应该声明为const 类型。如果在编写const 成员函
数时,不慎修改了数据成员,或者调用了其它非const 成员函数,编译器将指出错误,
这无疑会提高程序的健壮性。
以下程序中,类stack 的成员函数GetCount 仅用于计数,从逻辑上讲GetCount 应
当为const 函数。编译器将指出GetCount 函数中的错误。
class Stack
{
public:
void Push(int elem);
int Pop(void);
int GetCount(void) const; // const 成员函数
private:
int m_num;
int m_data[100];
};
int Stack::GetCount(void) const
{
++ m_num; // 编译错误,企图修改数据成员m_num
Pop(); // 编译错误,企图调用非const 函数
return m_num;
}
const 成员函数的声明看起来怪怪的:const 关键字只能放在函数声明的尾部,大
概是因为其它地方都已经被占用了。

 

3.const修饰返回值:

当返回值是自定义类型时,函数调用表达式是可以作为左值的

person buildArlen()
{
    person p(1, “arlen”);
    return p;
}

buildArlen() = person(11, “ii”);

当然,如果返回值是内建类型如int这些,函数调用表达式是不可以作左值的,你可以试试。所以说,const如果修改返回内建类型是没有意义的。

但修饰返回自定义类型的函数就有意义了,你猜对了,如果是const person buildArlen()这样的声明,在使用时把buildArlen()看作一个自定义类型的变量就可以了,这个变量不但已经有值而且这个变量还是const的。

const person buildArlen()
{
    person p(1, “arlen”);
    return p;
}

buildArlen() = person(11, “ii”); //报错!buildArlen() 是const的,不能再被赋值。

要注意:以下代码是ok的:

const person buildArlen(){…}

person ps = p.buildArlen();
ps.set_name(“xx”);  //这行是没有问题的。

4. const修饰指针类型返回值:

a. 定义:const person * buildArlen(){…}
    调用:const person *pt = buildArlen(); //必须在前面有const,无则报错

b. 定义:person const * buildArlen(){…}
    调用:const person *pt = buildArlen(); //是的,跟a是一样的。你也可以把const放在紧挨*的左侧:person const *pt = buildArlen();一个意思。

c. 定义:person * const buildArlen(){…}
    调用:
    person *pt= buildArlen();//前面加不加const都ok。

小结:如果返回值是自定义类型的指针,就可以直接将整个函数调用看作一个变量。为什么上述a,b在接受返回值时要在前面加const?因为普通变量也是如此的:

int i = 8;
const int *pi = &i;
const int *ptest = pi;//如果去掉前面的const则会报错。why?因为pi指向的变量值不能变,而ptest也是指向同一变量i的地址,所以ptest也必须用const修饰,否则i的值就可能会变。

总结:
返回自定义类型的函数调用可以作左值;作右值时类比普通变量。

返回自定义类型的指针的函数调用不可以作左值;作右值时类比普通变量。

返回内建类型或内建类型指针的函数调用不可以作左值;作右值类比普通变量。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值