• 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的值就可能会变。

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

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

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

  • 相关阅读:
    ORA-27302: failure occurred at: sskgpsemsper
    mysql 慢查询设置
    静默安装ORACLE数据库软件
    启动服务器上的所有oracle数据库
    shell tr 命令详解
    Hive安装
    hadoop2.7.2完全分布式环境搭建
    FastDFS
    aspnet_regiis加密文件提示路径中具有非法字符
    DataGridview绑定复杂对象
  • 原文地址:https://www.cnblogs.com/bdbw2012/p/3074434.html
Copyright © 2020-2023  润新知