C++沉思录笔记 —— 第十章:一个课堂练习的分析(下)

代码整理如下:

Frame_Pic.cpp

#include "Frame_Pic.h"
Frame_Pic::Frame_Pic(const Picture& pic, char c, char s, char t) :
                    p(pic), corner(c), sideborder(s), topborder(t) {}
int Frame_Pic::height() const{
    return p.height() + 2;
}
int Frame_Pic::width() const{
    return p.width() + 2;
}
void Frame_Pic::display(ostream& os, int row, int wd) const{
    if(row < 0 || row >= height()){
        pad(os, 0, wd);
    }else{
        if(row == 0 || row == height() - 1){
            os << corner;
            int i = p.width();
            while(--i >= 0)
                os << topborder;
            os << corner;
        }else{
            os << sideborder;
            p.display(os, row - 1, p.width());
            os << sideborder;
        }
        pad(os, width(), wd);
    }
}
Picture Frame_Pic::reframe(char c, char s, char t){
    return new Frame_Pic(::reframe(p, c, s, t), c, s, t);
}
 
 
Frame_Pic.h

#include "P_Node.h"
#include "Picture.h"

class Frame_Pic : public P_Node{
    friend Picture frame(const Picture&);
    friend Picture reframe(const Picture&, char, char, char);
   
    Frame_Pic(const Picture&, char='+', char='|', char ='-');
    int height() const;
    int width() const;
    void display(ostream&, int, int) const;
    Picture reframe(char, char, char);
       
    Picture p;
    char corner;
    char sideborder;
    char topborder;
};

Hcat_Pic.cpp

#include "Hcat_Pic.h"

Hcat_Pic::Hcat_Pic(const Picture& l, const Picture& r) : left(l), right(r) {}

int Hcat_Pic::height() const{
    return max(left.height(), right.height());
}

int Hcat_Pic::width() const{
    return left.width() + right.width();
}

void Hcat_Pic::display(ostream& os, int row, int wd) const{
    left.display(os, row, left.width());
    right.display(os, row, right.width());
    pad(os, width(), wd);
}

Picture Hcat_Pic::reframe(char c, char s, char t){
    return new Hcat_Pic(
        ::reframe(left, c, s, t),
        ::reframe(right, c, s, t)
    );
}

Hcat_Pic.h

#include "P_Node.h"
#include "Picture.h"
class Hcat_Pic : public P_Node{

    friend Picture operator|(const Picture&, const Picture&);

    friend Picture reframe(const Picture&, char, char, char);

   

    Hcat_Pic(const Picture&, const Picture&);

    int height() const;

    int width() const;

    void display(ostream&, int, int) const;

    Picture reframe(char, char, char);

       

    Picture left, right;

};

P_Node.cpp

#include "P_Node.h"
P_Node::P_Node() : use(1) {}
P_Node::~P_Node() {}
 
 
P_Node.h

#ifndef P_NODE_H
#define P_NODE_H
#include <iostream>
#include "Picture.h"
using namespace std;

class Picture;
class P_Node {
    friend class Picture;
    friend Picture reframe(const Picture&, char, char, char);
protected:
    P_Node();
    virtual ~P_Node();
    virtual int height() const = 0;
    virtual int width() const = 0;
    virtual void display(ostream&, int, int) const = 0;
    virtual Picture reframe(char, char, char) = 0;
    static int max(int x, int y) { return x > y ? x : y; }
    static void pad(ostream& os, int x, int y){
        for(int i = x; i < y; i++)
            os << " ";
    }
    int use;
};
#endif /*P_NODE_H*/

Picture.cpp
#include <iostream>
#include "Picture.h"
#include "String_Pic.h"
#include "Frame_Pic.h"
#include "Hcat_Pic.h"
#include "Vcat_Pic.h"
using namespace std;
Picture::Picture(const char* const* str, int n) : p(new String_Pic(str, n)) {}
Picture::Picture(const Picture& orig) : p(orig.p){
    orig.p->use++;
}
Picture::~Picture(){
    if(--p->use == 0)
        delete p;
}
Picture& Picture::operator=(const Picture& orig){
    orig.p->use++;
    if(--p->use == 0)
        delete p;
    p = orig.p;
    return *this;
}
Picture::Picture(P_Node* p_node) : p(p_node) {}
int Picture::height() const{
    return p->height();
}
int Picture::width() const{
    return p->width();
}
void Picture::display(ostream& o, int x, int y) const{
    p->display(o, x, y);
}
ostream& operator<<(ostream& os, const Picture& picture) {
    int ht = picture.height();
    for(int i = 0; i < ht; i++){
        picture.display(os, i, 0);
        os << endl;
    }
    return os;
}
Picture frame(const Picture& pic){
    return new Frame_Pic(pic);
}
Picture reframe(const Picture& pic, char c, char s, char t){
    return pic.p->reframe(c, s, t);
}
Picture operator|(const Picture& l, const Picture& r){
    return new Hcat_Pic(l, r);
}
Picture operator&(const Picture& t, const Picture& b){
    return new Vcat_Pic(t, b);
}
 
Picture.h
#ifndef PICTURE_H
#define PICTURE_H
#include <iostream>
#include "P_Node.h"
using namespace std;
class P_Node;
class Picture{
    friend ostream& operator <<(ostream& os,const Picture& p);
    friend Picture frame(const Picture&);
    friend Picture reframe(const Picture&, char, char, char);
    friend Picture operator|(const Picture&, const Picture&);   
    friend Picture operator&(const Picture&, const Picture&);
    friend class String_Pic;
    friend class Frame_Pic;
    friend class Hcat_Pic;
    friend class Vcat_Pic;
public:
    Picture() : p(0) {}
    Picture(const char* const*, int);
    Picture(const Picture&);
    ~Picture();
    Picture& operator=(const Picture&);
private:
    Picture(P_Node*);
    int height() const;
    int width() const;
    void display(ostream&, int, int) const;
    P_Node* p;
};
Picture reframe(const Picture&, char, char, char);
#endif /*PICTURE_H*/
 
String_Pic.cpp
#include "String_Pic.h"
#include <cstring>
#include <iostream>
using namespace std;
String_Pic::String_Pic(const char* const* p, int n) : data(new char* [n]), size(n){
    for(int i = 0; i < n; i++){
        data[i] = new char[strlen(p[i])+1];
        strcpy(data[i], p[i]);
    }
}
String_Pic::~String_Pic(){
    for(int i = 0; i < size; i++)
        delete[] data[i];
    delete[] data;
}
int String_Pic::height() const {
    return size;
}
int String_Pic::width() const {
    int n = 0;
    for(int i = 0; i < size; i++){
        n = max(n, strlen(data[i]));
    }
    return n;
}
void String_Pic::display(ostream& os, int row, int width) const{  
    int start = 0;
    if(row >= 0 && row < height()){
        os << data[row];
        start = strlen(data[row]);
    }
    pad(os, start, width);
}
Picture String_Pic::reframe(char, char, char){
    use++;
    return this;
}
 
String_pic.h
#include "P_Node.h"
class String_Pic : public P_Node{
    friend class Picture;
    String_Pic(const char* const*, int);
    ~String_Pic();
    int height() const;
    int width() const;
    void display(ostream&, int, int) const;
    Picture reframe(char, char, char);
    char** data;
    int size;
};
 
Vcat_Pic.cpp
#include "Vcat_Pic.h"
Vcat_Pic::Vcat_Pic(const Picture& t, const Picture& b) : top(t), bottom(b) {}
int Vcat_Pic::height() const{
    return top.height() + bottom.height();
}
int Vcat_Pic::width() const{
    return max(top.width(), bottom.width());
}
void Vcat_Pic::display(ostream& os, int row, int wd) const{
    if( row >= 0 && row < top.height())
        top.display(os, row, wd);
    else if(row < top.height() + bottom.height())
        bottom.display(os, row - top.height(), wd);
    else
        pad(os, 0, wd);
}
Picture Vcat_Pic::reframe(char c, char s, char t){
    return new Vcat_Pic(
        ::reframe(top, c, s, t),
        ::reframe(bottom, c, s, t)
    );
}
 
Vcat_Pic.h
 
#include "P_Node.h"
#include "Picture.h"
class Vcat_Pic : public P_Node{
    friend Picture operator&(const Picture&, const Picture&);
    friend Picture reframe(const Picture&, char, char, char);
   
    Vcat_Pic(const Picture&, const Picture&);
    int height() const;
    int width() const;
    void display(ostream&, int, int) const;
    Picture reframe(char, char, char);
       
    Picture top, bottom;
};
 
 
test.cpp
 
 #include "Picture.h"
 #include "iostream"
 using namespace std;
 const char* init[] = {"Paris", "in the", "Spring"};
 
 int main(int argc, char const *argv[])
 {
    Picture p(init, 3);
   
    Picture q = frame(p);
    cout << frame(q & (p | q)) << endl;
   
    cout << reframe(q,'*','*','*') << endl;
   
    return 0;
 }

猜你喜欢

转载自www.cnblogs.com/vonyoven/p/11788606.html