《C++沉思录》第十章 编译同不过
本人模仿书上写了代码,可是编译同不过,很是纠结,求各位大神帮忙看看。
picture.h
#ifndef PICTURE_H
#define PICTURE_H
#include <iostream>
class P_Node;
class Picture
{
friend std::ostream& operator<<(std::ostream&, const Picture&);
friend Picture frame(const Picture&);
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(const char* const*, int);
Picture(const Picture&);
Picture& operator=(const Picture&);
~Picture();
private:
P_Node* m_p;
//这个构造函数作为隐式转型操作符,应用于链接操作
Picture(P_Node*);
int height() const;
int width() const;
void display(std::ostream&, int, int) const;
};
class P_Node
{
friend class Picture;
public:
int max(int x, int y) const;
protected:
P_Node();
virtual ~P_Node();
virtual int height() const = 0;
virtual int width() const = 0;
virtual void display(std::iostream&, int, int) const = 0;
private:
int m_use;
};
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(std::iostream&, int, int) const;
char** m_data;
int m_size;
};
class Frame_Pic: public P_Node
{
friend Picture frame(const Picture&);
Frame_Pic(const Picture&);
int height() const;
int width() const;
void display(std::iostream&, int, int) const;
Picture m_p;
};
class VCat_Pic: public P_Node
{
friend Picture operator&(const Picture&, const Picture&);
VCat_Pic(const Picture&, const Picture&);
int height() const;
int width() const;
void display(std::iostream&, int, int) const;
Picture m_top;
Picture m_bottom;
};
class HCat_Pic: public P_Node
{
friend Picture operator|(const Picture&, const Picture&);
HCat_Pic(const Picture&, const Picture&);
int height() const;
int width() const;
void display(std::iostream&, int, int) const;
Picture m_left;
Picture m_right;
};
#endif // PICTURE_H
#include "picture.h"
#include "string.h"
int P_Node::max(int x, int y) const
{
return x > y ? x : y;
}
P_Node::P_Node()
:m_use(1)
{
}
P_Node::~P_Node()
{
}
/************end Picture****************/
String_Pic::String_Pic(const char* const* array, int n)
:m_data(new char* [n]), m_size(n)
{
for (int i=0; i<n; ++i)
{
m_data[i] = new char[strlen(array[i]) + 1];
strcpy(m_data[i], array[i]);
}
}
String_Pic::~String_Pic()
{
for (int i=0; i<m_size; ++i)
delete[] m_data[i];
delete[] m_data;
}
int String_Pic::height() const
{
return m_size;
}
int String_Pic::width() const
{
int n = 0;
for (int i=0; i<m_size; ++i)
{
n = max(n, strlen(m_data[i]));
}
return n;
}
static void pad(std::ostream& os, int x, int y)
{
for (int i=x; i<y; ++i)
{
os << " ";
}
}
void String_Pic::display(std::iostream& os, int row, int width) const
{
int start = 0;
if (row>=0 && row<= height())
{
os << m_data[row];
start = strlen(m_data[row]);
}
pad(os, start, width);
}
/************end String_Pic****************/
Picture frame(const Picture& pic)
{
return new Frame_Pic(pic);
}
Frame_Pic::Frame_Pic(const Picture& pic)
:m_p(pic)
{
}
int Frame_Pic::height() const
{
return m_p.height() + 2;
}
int Frame_Pic::width() const
{
return m_p.width() + 2;
}
void Frame_Pic::display(std::iostream& os, int row, int width) const
{
if (row<0 || row>=height())
pad(os, 0, width);
else
{
if (row==0 || row==height()-1)
{
//顶框和底框
os << "+";
int i = m_p.width();
while (--i >= 0)
os<< "-";
os << "+";
}
else
{
//内部行
os << "|";
m_p.display(os, row-1, m_p.width());
os << "|";
}
pad(os, this->width(), width);
}
}
/************end Frame_Pic****************/
VCat_Pic::VCat_Pic(const Picture& top, const Picture& bottom)
:m_top(top), m_bottom(bottom)
{
}
Picture operator&(const Picture& top, const Picture& bottom)
{
return new VCat_Pic(top, bottom);
}
int VCat_Pic::height() const
{
return m_top.height() + m_bottom.height();
}
int VCat_Pic::width() const
{
return max(m_top.width(), m_bottom.width());
}
void VCat_Pic::display(std::iostream& os, int row , int width) const
{
if (row>=0 && row< m_top.height())
{
m_top.display(os, row, width);
}
else if (row < m_top.height() + m_bottom.height())
{
m_bottom.display(os, row-m_top.height(), width);
}
else
{
pad(os, 0, width);
}
}
/************end VCat_Pic****************/
HCat_Pic::HCat_Pic(const Picture& left, const Picture& right)
:m_left(left), m_right(right)
{
}
Picture operator|(const Picture& left, const Picture& right)
{
return new HCat_Pic(left, right);
}
int HCat_Pic::height() const
{
return max(m_left.height(), m_right.height());
}
int HCat_Pic::width() const
{
return m_left.width() + m_right.width();
}
void HCat_Pic::display(std::iostream& os, int row, int width) const
{
m_left.display(os, row, m_left.width());
m_right.display(os, row, m_right.width());
pad(os, this->width(), width);
}
/************end HCat_Pic****************/
Picture::Picture(P_Node* p)
:m_p(p)
{
}
Picture::Picture(const char* const* array, int n)
:m_p(new String_Pic(array, n))
{
}
Picture::Picture(const Picture& orig)
:m_p(orig.m_p)
{
orig.m_p->m_use++;
}
Picture& Picture::operator=(const Picture& orig)
{
++orig.m_p->m_use;
if (--m_p->m_use == 0)
delete m_p;
m_p = orig.m_p;
return *this;
}
Picture::~Picture()
{
if (--m_p->m_use == 0)
delete m_p;
}
int Picture::height() const
{
return m_p->height();
}
int Picture::width() const
{
return m_p->width();
}
void Picture::display(std::ostream& o, int x, int y) const
{
m_p->display(o, x, y);
}
std::ostream& operator<<(std::ostream& os, const Picture& picture)
{
int ht = picture.height();
for (int i=0; i<ht; ++i)
{
picture.display(os, i, picture.width());
os << std::endl;
}
return os;
}
/************end Picture****************/
#include <iostream>
#include "picture.h"
using namespace std;
int main()
{
cout << "Hello World!" << endl;
return 0;
}
//查找替换把所有iostream转成ostream,你没仔细看哦
void VCat_Pic::display(std::iostream& os, int row , int width) const