【共读Primer】63.[7.3]类的其他特性 Page243

类型成员

class Screen
{
public:
    typedef std::string::size_type pos; // 类型成员 
    //using pos = std::string::size_type; // C++11 风格的类型别名定义,与上一行效果一致
private:
    pos cursor = 0;
    pos height = 0, width = 0;
    std::string contents;
};

类型成员的定义需要注意的是,必须先定义后使用,所以一般定义在类的开头部位。

成员函数及内联成员函数、重载类型

class Screen
{
public:
    typedef std::string::size_type pos; // 类型成员 
    //using pos = std::string::size_type; // C++11 风格的类型别名定义,与上一行效果一致
    Screen()=default;  // 因为存在带参构造函数,如果需要使用无参默认构造函数则需要显示声明
    Screen(pos ht, pos wd, char c)
        : height(ht), width(wd),contents(ht*wd,c){}
    char get() const{return contents[cursor];}    // 类内定义,默认为内联函数(隐式内联)
    inline char get(pos ht, pos wd) const; // 类外定义,但是具有内联关键字为内联函数(显示内联)
    Screen &move(pos r, pos c); // 在定义时被设为内联函数
private:
    pos cursor = 0;
    pos height = 0, width = 0;
    std::string contents;
};

inline Screen &Screen::move(pos r, pos c) // 在定义时指定为内联
{
    pos row = r * width;    
    cursor = row + c;
    return *this; // 返回自身的引用
}

char Screen::get(pos r, pos c) const
{
    pos row = r * width;
    return contents[row + c];
}

如果在有其他构造函数的情况下,仍然需要使用默认构造函数,请显示的声明它。

内联函数可以在声明的时候指定,也可以在定义的时候指定,也可以两处都指定。

类内部定义的函数默认为内联函数。

下面给出类型的完整代码

class Screen
{
public:
    typedef std::string::size_type pos; // 类型成员 
    //using pos = std::string::size_type; // C++11 风格的类型别名定义,与上一行效果一致
    Screen()=default;  // 因为存在带参构造函数,如果需要使用无参默认构造函数则需要显示声明
    Screen(pos ht, pos wd, char c)
        : height(ht), width(wd),contents(ht*wd,c){}
    char get() const{return contents[cursor];}    // 类内定义,默认为内联函数(隐式内联)
    inline char get(pos ht, pos wd) const; // 类外定义,但是具有内联关键字为内联函数(显示内联)
    Screen &move(pos r, pos c); // 在定义时被设为内联函数
    void some_member() const;
public:
    Screen &set(char);
    Screen &set(pos, pos, char);
    Screen &display(std::ostream &os){do_display(os); return *this;}
    const Screen &display(std::ostream &os) const {do_display(os); return *this;}
private:
    void do_display(std::ostream &os) const {os << contents;}
private:
    pos cursor = 0;
    pos height = 0, width = 0;
    std::string contents;
    mutable size_t access_ctr; // 在const对象中也可以被修改
};

void Screen::some_member() const
{
    ++access_ctr;     // 用于计数被调用次数
}

inline Screen &Screen::move(pos r, pos c) // 在定义时指定为内联
{
    pos row = r * width;    
    cursor = row + c;
    return *this; // 返回自身的引用
}

char Screen::get(pos r, pos c) const
{
    pos row = r * width;
    return contents[row + c];
}

inline Screen &Screen::set(char c)
{
    contents[cursor] = c;
    return *this;
}

inline Screen &Screen::set(pos r, pos col, char ch)
{
    contents[r * width + col] = ch;
    return *this;
}

 需要着重简述一下的是do_display函数,

为什么要定义一个如此简单的函数,原因如下:

1. 避免重复代码

2.预期该处可能出现变化

3.可以增添一些调试信息,在发布版本中去除

4.隐式内联函数不会增加运行开销

posted @ 2018-09-19 09:18  chattyku  阅读(130)  评论(0编辑  收藏  举报