六一的部落格


关关难过关关过,前路漫漫亦灿灿。




成员名字声明和函数定义的处理

编译时先处理类成员名字的声明,再处理类函数成员的定义


在类外定义成员函数

需要在函数名之前给出类名,进入到类的作用域. 形参列表和函数体都在类的作用域之中

类的返回类型不在类的作用域中

1double Sales_data::avg_price() const
2{
3    if (units_sold)
4        return revenue / units_sold;
5    else
6        return 0;
7}

隐式this

对于非静态成员函数,一定是通过类对象调用成员函数

函数的传参不包括this指针,但成员函数拥有名为this的参数,指向调用该成员函数的对象

this指针具有顶层const. 即, 不可以使this指向其他对象

 1class Sales_data
 2{
 3public:
 4    string isbn() const { return bookNo; }
 5    Sales_data combine(const Sales_data&);
 6    double avg_price() const;
 7    string bookNo;
 8    unsigned units_sold = 0;
 9    double revenue = 0.0;
10};
11ostream &print(ostream&, const Sales_data&);
12istream &read(istream&, Sales_data&);
1Sales_data total;
2total.isbn();        // Sales_data::isbn(&total);    this = &total;
1string Sales_data::isbn() const 
2{ 
3    return bookNo;     // return this->bookNo;
4}

返回this所指对象

1Sales_data& Sales_data::combine(const Sales_data &rhs)
2{
3    units_sold += rhs.units_sold;
4    revenue += rhs.revenue;
5
6    return *this; // 返回非常量对象;this指针的类型为Sales_data *const
7}

const函数

用来修改this的类型, 使之具有底层const. 即, 此时不可以通过this对对象执行写操作

回收了类对象的写权限


const函数与this指针

  1. this具有底层const
  2. 通过this返回的对象具有顶层const

const函数的定义和声明

均要在形参列表之后给出const关键字

  1. 隐式内联函数

    1struct Sales_data
    2{
    3    Sales_data &combine(const Sales_data &);            // this指针的类型为Sales_data *const
    4    string isbn() const { return bookNo; }              // this指针的类型为const Sales_data *const
    5
    6private:
    7    string bookNo;
    8};
  2. 声明和定义处均给出const关键字

     1struct Sales_data
     2{
     3    double avg_price() const;
     4private:
     5    string bookNo;
     6    unsigned units_sold = 0;
     7    double revenue = 0.0;
     8};
     9
    10double Sales_data::avg_price() const
    11{
    12    if (units_sold)
    13        return revenue / units_sold;
    14    else
    15        return 0;
    16}

如果类对象具有顶层const, 只能对其调用const成员函数

如果类对象不具有顶层const, 可以对其调用类的所有public接口


类的成员函数可基于const重载

 1class Screen
 2{
 3public:
 4    typedef string::size_type pos;
 5    Screen &set(char);
 6    Screen &move(pos r, pos c);
 7
 8    Screen() = default;
 9
10    Screen(pos ht, pos wd, char c = ' ') : height(ht), width(wd), contents(ht * wd, c) { }
11
12    const Screen &display(ostream &os) const { do_display(os); return *this; }
13    Screen &display(ostream &os) { do_display(os); return *this; }
14
15private:
16    pos cursor = 0;
17    pos height = 0, width = 0;
18    string contents;
19    void do_display(ostream &os) const { os << contents; }
20// 当一个成员调用另一个成员时,this指针在其中隐式地传递;
21// 由display的非常量版本调用do_display时,它的this指针将隐式地从指向非常量的指针转换成指向常量的指针
22// 避免在多处使用同样的代码
23// 本身就是内联函数,不会添加额外的运行时开销
24};
25
26inline screen &screen::set(char c)
27{
28    contents[cursor] = c;
29    return *this;
30}
31
32Screen myScreen(5, 3);
33const Screen blank(5, 3);
34
35myScreen.move(4, 0).set('#');            // move和set的返回值都是非常量引用
36blank.display(cout).set('#');            // 错误: blank是常量对象,匹配const Screen &display(ostream&) const;而set非const成员,调用失败

可在const函数中对可变数据成员执行写操作


内联函数

  1. 隐式内联函数

    不使用关键字inline, 但在类内给出函数定义

  2. 在类外定义内联函数

    需给出关键字inline

    在类内声明成员函数, 在类外定义成员函数; 声明和定义其中一处给出inline关键字即可

    可以同时给出


类的函数成员



成员名字声明和函数定义的处理

编译时先处理类成员名字的声明,再处理类函数成员的定义


在类外定义成员函数

需要在函数名之前给出类名,进入到类的作用域. 形参列表和函数体都在类的作用域之中

类的返回类型不在类的作用域中

1double Sales_data::avg_price() const
2{
3    if (units_sold)
4        return revenue / units_sold;
5    else
6        return 0;
7}

隐式this

对于非静态成员函数,一定是通过类对象调用成员函数

函数的传参不包括this指针,但成员函数拥有名为this的参数,指向调用该成员函数的对象

this指针具有顶层const. 即, 不可以使this指向其他对象

 1class Sales_data
 2{
 3public:
 4    string isbn() const { return bookNo; }
 5    Sales_data combine(const Sales_data&);
 6    double avg_price() const;
 7    string bookNo;
 8    unsigned units_sold = 0;
 9    double revenue = 0.0;
10};
11ostream &print(ostream&, const Sales_data&);
12istream &read(istream&, Sales_data&);
1Sales_data total;
2total.isbn();        // Sales_data::isbn(&total);    this = &total;
1string Sales_data::isbn() const 
2{ 
3    return bookNo;     // return this->bookNo;
4}

返回this所指对象

1Sales_data& Sales_data::combine(const Sales_data &rhs)
2{
3    units_sold += rhs.units_sold;
4    revenue += rhs.revenue;
5
6    return *this; // 返回非常量对象;this指针的类型为Sales_data *const
7}

const函数

用来修改this的类型, 使之具有底层const. 即, 此时不可以通过this对对象执行写操作

回收了类对象的写权限


const函数与this指针

  1. this具有底层const
  2. 通过this返回的对象具有顶层const

const函数的定义和声明

均要在形参列表之后给出const关键字

  1. 隐式内联函数

    1struct Sales_data
    2{
    3    Sales_data &combine(const Sales_data &);            // this指针的类型为Sales_data *const
    4    string isbn() const { return bookNo; }              // this指针的类型为const Sales_data *const
    5
    6private:
    7    string bookNo;
    8};
  2. 声明和定义处均给出const关键字

     1struct Sales_data
     2{
     3    double avg_price() const;
     4private:
     5    string bookNo;
     6    unsigned units_sold = 0;
     7    double revenue = 0.0;
     8};
     9
    10double Sales_data::avg_price() const
    11{
    12    if (units_sold)
    13        return revenue / units_sold;
    14    else
    15        return 0;
    16}

如果类对象具有顶层const, 只能对其调用const成员函数

如果类对象不具有顶层const, 可以对其调用类的所有public接口


类的成员函数可基于const重载

 1class Screen
 2{
 3public:
 4    typedef string::size_type pos;
 5    Screen &set(char);
 6    Screen &move(pos r, pos c);
 7
 8    Screen() = default;
 9
10    Screen(pos ht, pos wd, char c = ' ') : height(ht), width(wd), contents(ht * wd, c) { }
11
12    const Screen &display(ostream &os) const { do_display(os); return *this; }
13    Screen &display(ostream &os) { do_display(os); return *this; }
14
15private:
16    pos cursor = 0;
17    pos height = 0, width = 0;
18    string contents;
19    void do_display(ostream &os) const { os << contents; }
20// 当一个成员调用另一个成员时,this指针在其中隐式地传递;
21// 由display的非常量版本调用do_display时,它的this指针将隐式地从指向非常量的指针转换成指向常量的指针
22// 避免在多处使用同样的代码
23// 本身就是内联函数,不会添加额外的运行时开销
24};
25
26inline screen &screen::set(char c)
27{
28    contents[cursor] = c;
29    return *this;
30}
31
32Screen myScreen(5, 3);
33const Screen blank(5, 3);
34
35myScreen.move(4, 0).set('#');            // move和set的返回值都是非常量引用
36blank.display(cout).set('#');            // 错误: blank是常量对象,匹配const Screen &display(ostream&) const;而set非const成员,调用失败

可在const函数中对可变数据成员执行写操作


内联函数

  1. 隐式内联函数

    不使用关键字inline, 但在类内给出函数定义

  2. 在类外定义内联函数

    需给出关键字inline

    在类内声明成员函数, 在类外定义成员函数; 声明和定义其中一处给出inline关键字即可

    可以同时给出