美文网首页
(十七)C++篇-自定义类(二)

(十七)C++篇-自定义类(二)

作者: GoodTekken | 来源:发表于2022-06-28 10:27 被阅读0次

    扩展 Screen 类以包含 move、set 和 display 操作:
    myScreen.move(4,0).set('#').display(cout);

    测试代码:

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    class Screen
    {
    public:
        typedef string::size_type index;
        char get() const{return contents[cursor];}
        inline char get(index ht,index wd) const;
        index get_cursor() const;
        Screen(index hght,index wdth,const string &cntnts);
        
        Screen& move(index r,index c);
        Screen& set(char);
        Screen& display(ostream &os);
        
    private:
        std::string contents;
        index cursor;
        index height,width;
    };
    
    
    Screen::Screen(index hght,index wdth,const string &cntnts):contents(cntnts),cursor(0),height(hght),width(wdth)
    {
    }
    
    char Screen::get(index r,index c) const
    {
        index row=r*width;
        return contents[row + c];
    }
    
    inline Screen::index Screen::get_cursor() const
    {
        return cursor;
    }
    
    Screen& Screen::set(char c)
    {
        contents[cursor] = c;
        return *this;
    }
    
    Screen& Screen::move(index r,index c)
    {
        index row=r*width;
        cursor=row+c;
        return *this;
    }
    
    Screen& Screen::display(ostream &os)
    {
        os<<contents;
        return *this;
    }
    
    int main()
    {
        Screen myScreen(5,6,"aaaaa\naaaaa\naaaaa\naaaaa\naaaaa\n");
        myScreen.move(4,0).set('#').display(cout);
        
        return 0;
    }   
    

    输出结果:

    tekken@tekken:~/C++WS$ ./a.out 
    aaaaa
    aaaaa
    aaaaa
    aaaaa
    #aaaa
    

    这个解决方法已满足题目提出的要求,但存在一些缺陷:
    (1)创建Screen对象时必须给出表示整个屏幕内容的字符串,即使有些位置上没有内容。
    解决:

    //修改构造函数
    Screen::Screen(index hght,index wdth,const string &cntnts = ""):contents(cntnts),cursor(0),height(hght),width(wdth)
    {
        //将整个屏幕内容置为空格
        contents.assign(hght*wdth,' ');
        //用形参string对象的内容设置屏幕的相应字符
        if(cntnts.size()!=0)
            contents.replace(0,cntnts.size(),cntnts);
    }
    

    (2)显示的屏幕内容没有恰当地分行,而是连续显示,因此(4,0)位置上的‘#’,在实际显示时不一定正好在屏幕的(4,0)位置,显示结果较差。
    解决:

    Screen& Screen::display(ostream &os)
    {
        string::size_type index =0;
        while(index !=contents.size())
        {
            os<<contents[index];
            if((index+1)%width==0)
            {
                os<<'\n';
            }
            ++index;
        }
        return *this;
    }
    

    (3)如果创建的Screen对象是一个const对象,则不能使用display函数进行显示。(因为const对象只能显示const成员)。
    解决:
    在Screen类定义体中增加如下函数声明
    const Screen& display(ostream &os) const;
    并在Screen类定义体外增加函数的定义

    const Screen& Screen::display(ostream &os) const
    {
        string::size_type index =0;
        while(index !=contents.size())
        {
            os<<contents[index];
            if((index+1)%width==0)
            {
                os<<'\n';
            }
            ++index;
        }
        return *this;
    }
    

    (4)如果move操作的目的位置超出了屏幕的边界,会出现运行时错误。
    解决:
    对move操作的行和列标号进行检查避免操作越界。

    Screen& Screen::move(index r,index c)
    {
        //行,列号均从0开始
        if(r>=height||r>=width)
        {
            cerr<<"invalid row or column"<<endl;
            throw EXIT_FAILURE;
        }
        index row=r*width;
        cursor=row+c;
        return *this;
    }
    

    因此,优化后的完成代码如下:

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    class Screen
    {
    public:
        typedef string::size_type index;
        char get() const{return contents[cursor];}
        inline char get(index ht,index wd) const;
        index get_cursor() const;
        Screen(index hght,index wdth,const string &cntnts);
        
        Screen& move(index r,index c);
        Screen& set(char);
        Screen& display(ostream &os);
        const Screen& display(ostream &os) const;
        
    private:
        std::string contents;
        index cursor;
        index height,width;
    };
    
    
    Screen::Screen(index hght,index wdth,const string &cntnts = ""):contents(cntnts),cursor(0),height(hght),width(wdth)
    {
        //将整个屏幕内容置为空格
        contents.assign(hght*wdth,' ');
        //用形参string对象的内容设置屏幕的相应字符
        if(cntnts.size()!=0)
            contents.replace(0,cntnts.size(),cntnts);
    }
    
    char Screen::get(index r,index c) const
    {
        index row=r*width;
        return contents[row + c];
    }
    
    inline Screen::index Screen::get_cursor() const
    {
        return cursor;
    }
    
    Screen& Screen::set(char c)
    {
        contents[cursor] = c;
        return *this;
    }
    
    Screen& Screen::move(index r,index c)
    {
        //行,列号均从0开始
        if(r>=height||c>=width)
        {
            cerr<<"invalid row or column"<<endl;
            cerr<<EXIT_FAILURE<<endl;
            throw EXIT_FAILURE;
        }
        index row=r*width;
        cursor=row+c;
        return *this;
    }
    
    Screen& Screen::display(ostream &os)
    {
        string::size_type index =0;
        while(index !=contents.size())
        {
            os<<contents[index];
            if((index+1)%width==0)
            {
                os<<'\n';
            }
            ++index;
        }
        return *this;
    }
    
    const Screen& Screen::display(ostream &os) const
    {
        string::size_type index =0;
        while(index !=contents.size())
        {
            os<<contents[index];
            if((index+1)%width==0)
            {
                os<<'\n';
            }
            ++index;
        }
        return *this;
    }
    
    int main()
    {
        Screen myScreen(5,6,"aaaaa\naaaaa\naaaaa\naaaaa\naaaaa\n");
        myScreen.move(3,7).set('e').display(cout);
        
        return 0;
    }
    

    相关文章

      网友评论

          本文标题:(十七)C++篇-自定义类(二)

          本文链接:https://www.haomeiwen.com/subject/dydavrtx.html