c++沉思录第十章的例子

调试了好久,出现了好大问题。关于虚函数和纯虚函数的知识需要我们好好注意。

#ifndef NEWPICTURE_H
#define NEWPICTURE_H
#include<iostream>
using namespace std;
class P_Node
{
	friend class Picture;
protected:
	P_Node();
	virtual ~P_Node(){};
	virtual int width()const=0;
	virtual int height()const=0;
	virtual void display(ostream &, int, int)const=0;
	int max(int x, int y)const { return x > y ? x : y; }
	void pad(ostream & os, int x, int y)const ;
private:
	int use;
};
class Picture
{
	friend class String_Pic;
	friend class Frame_Pic;
	friend class Hcat_Pic;
	friend class Vcat_Pic;
public:
	Picture();
	Picture(const char * const *, int);
	Picture(const Picture &);
	~Picture();
	Picture & operator =(const Picture &);
	P_Node * p;
	Picture(P_Node * m);
	int height()const;
	int width()const;
	void display(ostream &, int, int)const;
	friend ostream & operator <<(ostream & os, const Picture & p);
	friend Picture frame(const Picture & p);
	friend Picture operator & (const Picture & p, const Picture & q);
	friend Picture operator | (const Picture & p, const Picture & q);
};
class String_Pic :public P_Node
{
	friend class Picture;
	String_Pic(const char* const * arr, int n);
	~String_Pic();
	char** data;
	int size;
	int height()const;
	int width()const;
	void display(ostream &, int, int)const;
};

class Frame_Pic :public P_Node
{
	friend Picture frame(const Picture &);

	int height()const;
	int width()const;
	void display(ostream &, int, int)const;
	Frame_Pic(const Picture &);
	Picture p;
};

class Vcat_Pic :public P_Node
{
	friend Picture operator &
	(const Picture & n, const Picture & m);
	Vcat_Pic(const Picture & n, const Picture & m);
	int height()const;
	int width()const;
	void display(ostream &, int, int)const;
	Picture top, bottom;
};

class Hcat_Pic :public P_Node
{
	friend Picture operator |
	(const Picture & n, const Picture & m);
	Hcat_Pic(const Picture & n, const Picture & m);
	int height()const;
	int width()const;
	void display(ostream &, int, int)const;
	Picture left,right;
};

Picture::Picture(const Picture & m) :p(m.p)
{
	m.p->use++;
}
Picture::Picture(P_Node * m) : p(m){}
Picture::~Picture()
{
	if (--p->use == 0)
		delete p;
}
Picture& Picture::operator=(const Picture & q)
{
	q.p->use++;
	if (--p->use == 0)
		delete p;
	p = q.p;
	return *this;
}
int Picture::height()const{ return p->height(); }
int Picture::width()const { return p->width(); }
void Picture::display(ostream & os, int n, int m)const
{
	p->display(os, n, m);
}
Picture::Picture(const char* const * arr, int n) :p(new String_Pic(arr, n)){}
P_Node::P_Node() :use(1){}

String_Pic::String_Pic(const char * const * arr, int n)
: data(new char*[n]), size(n)
{
	for (int i = 0; i < n; ++i)
	{
		data[i] = new char[strlen(arr[i]) + 1];
		strcpy_s(data[i],strlen(arr[i])+1,arr[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);
}
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 ( 0 == row  || row == height() - 1)
		{
			os << "+";
			int i = p.width();
			while (--i >= 0)os << "-";
			os << "+";
		}
		else
		{
			os << "|";
			p.display(os, row - 1, p.width());
			os << "|";
		}
		pad(os, width(), wd);
	}
}
Frame_Pic::Frame_Pic(const Picture & m) :p(m){}
Picture frame(const Picture & m)
{
	return new Frame_Pic(m);
}
Vcat_Pic::Vcat_Pic(const Picture & t, const Picture & b) : top(t), bottom(b){}
Hcat_Pic::Hcat_Pic(const Picture & l, const Picture & r) : left(l),right(r){}
Picture operator &(const Picture & n, const Picture & m)
{
	return new Vcat_Pic(n, m);
}
Picture operator |(const Picture & n, const Picture & m)
{
	return new Hcat_Pic(n, m);
}
int Vcat_Pic::height()const{ return top.height() + bottom.height(); }
int Vcat_Pic::width()const{ return max(top.width(), bottom.width()); }
int Hcat_Pic::height()const{ return max(left.height(), right.height()); }
int Hcat_Pic::width()const{ return left.width()+ right.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);
	}
}
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);
}
void P_Node::pad(ostream & os, int x, int y)const
{
	for (int i = x; i < y; ++i)
		os << " ";
}

ostream & operator <<(ostream & os, const Picture & p)
{
	int ht = p.height();
	for (int i = 0; i < ht; ++i)
	{	p.display(os, i, 0); os << endl;}
	return os;
}
#endif
#include"NewPicture.h"
#include<iostream>
using namespace std;
int main()
{
	char * init[] = { "Summer", "love", "Xieweizhong" };
	Picture p(init, 3);
	cout << p << endl;
	cout << frame((p | frame(p)) | (p | frame(p))) << endl;
	cout << frame((p & frame(p)) | (p | frame(p))) << endl;
	cout << frame((p | frame(p)) | (p & frame(p))) << endl;
	cout << frame((p & frame(p)) | (p & frame(p))) << endl;
	cout << frame((p | frame(p)) & (p | frame(p))) << endl;
	cout << frame((p & frame(p)) & (p | frame(p))) << endl;
	cout << frame((p | frame(p)) & (p & frame(p))) << endl;
	cout << frame((p & frame(p)) & (p & frame(p))) << endl;
	return 0;
}

时间: 2024-09-30 16:40:44

c++沉思录第十章的例子的相关文章

迷你MVVM框架 avalonjs 沉思录 第3节 动态模板

模板的发明是编程史上的一大里程碑,让我们摆脱了烦锁且易出错的字符串拼接,维护性大大提高. 都在JSP,ASP时代,人们已经学会使用include等语句,将多个页面片断拼接成一个页面. 此外,为了将数据库中的数据或业务中用到的变量输出到页面,我们需要将页面某个地方标记一下,将变量塞到里面去. 最后,出于方便循环输出一组数据,就需要将each语句从HTML里撕开一道口子,加上其他什么if语句,页面上其实变撕裂成两部分 一种是与后端语言相近的逻辑部分,一个是够为纯净的HTML部分,到最后,模板引擎就发

《C++沉思录》:类设计者的核查表——有关class的11问

本文的11个问题提取自<C++沉思录>第四章.所有问题的说明均为自己补充. 1 你的类需要一个构造函数吗? --正确的定义构造函数,把握好构造函数的职能范围 有些类太简单,它们的结构就是它们的接口,所以不需要构造函数. class print{ void print1(){cout<<"1"<<endl;} void print2(){cout<<"2"<<endl;} void print3(){cout

C++沉思录第八章算数表达式树的面向对象问题的分析

刚开始看沉思录,觉得太枯燥.到了第八章,作者关于面向对象问题的分析,我follow书上的设计开发,理解了一些以前只是在书上看到的概念. 给自己做几点注解吧: 1.虚基类用来表达所有的继承类的共有特点,在这个例子中,所有的继承类都要有输出和求值计算,所以我们把这两个函数定义为虚函数. 2.虚基类必须至少含有一个纯虚函数.该纯虚函数可以定义也可以不定义. 3.我们要保证由虚基类派生出来的类的对象能被正确的析构,所以将虚基类的析构函数定义为虚函数. 4.对于虚函数如果没有定义,也应该使用一对{}来表明

RxJava 沉思录(一):你认为 RxJava 真的好用吗?

本人两年前第一次接触 RxJava,和大多数初学者一样,看的第一篇 RxJava 入门文章是扔物线写的<给 Android 开发者的 RxJava 详解>,这篇文章流传之广,相信几乎所有学习 RxJava 的开发者都阅读过.尽管那篇文章定位读者是 RxJava 入门的初学者,但是阅读完之后还是觉得懵懵懂懂,总感觉依然不是很理解这个框架设计理念以及优势. 随后工作中有机会使用 RxJava 重构了项目的网络请求以及缓存层,期间陆陆续续又重构了数据访问层,以及项目中其他的一些功能模块,无一例外,我

C++沉思录之二——虚函数使用的时机

虚函数使用的时机 为什么虚函数不总是适用? 1. 虚函数有事会带来很大的消耗: 2. 虚函数不总是提供所需的行为: 3. 当我们不考虑继承当前类时,不必使用虚函数. 必须使用虚函数的情况: 1. 当你想删除一个表面上指向基类对象,实际却是指向派生类对象的指针,就需要虚析构函数. C++沉思录之二--虚函数使用的时机,布布扣,bubuko.com

个性化的亲切——《沉思录》引发的感悟

记得初中那阵子,曾经追过明星,甚至美的标准也变成了他——恨不得所有的明星都是长的和他一样,唱的和他一样.除了他的歌,我几乎欣赏不了其他人的歌. 还记得差不多在那个年纪,曾经幻想过世界“大统”——我认为“大统”是达到“大同”,消弭纷争的有效方式.惭愧,后来知道希特勒也是这么想的.此乃后话,不提. 也几乎是那个时候,我不愿再做“出头鸟”,我相信“人多力量大”,我总愿意融在身边的“圈子”,不想显得自己不合群. 个性化,在我们的应试教育体制中从来都没有得到特别的提倡,如果没有良师益友的及时提点,一定会让

迷你MVVM框架 avalonjs 沉思录 第1节 土耳其开局

#cnblogs_post_body p{ text-indent:2em; margin-top: 1em; } 正如一切传说的开端那样,有一远古巨神开天辟地,然后就是其他半神喧宾夺主.我们对最巨贡献与创建力的远古巨神懵懂不知,却对巫师们的话语津津乐道.这同样也是我们前端的现实. MVVM是来自.NET,另一个遥远的界域.前端,相对于后端,怎么看都是蛮夷之地.JS这个肩负着前端一切交互工作的语言,竟然被视为恶魔,屡屡被屏蔽禁用.些微可用的脚本,变量与函数没有组织地野蛮生长着,直到JAVA的传教

Trie树沉思录(1)

发现自己已经很久没有写解题报告了,很大一部分是因为懒,做完题之后不想再怎样了~不过最近发现写解题报告确实是有好处的,一方面可以复习,一方面可以梳理.还有就是可以给自己的岁月留下一点什么东西~今天是五一劳动节,就应该要劳动!我要重新着手写我的博客了~ 最近几个星期都在研究字符串,有点难,不过到现在为止Trie数学得还算是有那么点意思,写篇博文来记录一下! (关于Trie数是什么东西我就不想写了,我只写我个人的一些思考) Trie树通过共享前缀来达到了节约内存的目标,十分的强大!关于他的实现大概有两

PHP沉思录-第六篇-Drupal的性能问题-左轻侯-《程序员》2008年11月号

创建时间:2008-11-09 01:12:51   最后修改时间:2008-11-09 01:12:51 本文发表在<程序员>杂志2008年第11期 PHP沉思录之六:Drupal的性能问题 左轻侯 Drupal是一个基于PHP的开源CMS系统,也是我认为技术上实现得最好的一个PHP应用.Drupal的架构非常优秀,通过微内核+plugin的方式,实现了极佳的扩展性,从而使Drupal远远超出一般的CMS这一范畴.从这个意义上来说,把Drupal称为Web OS似乎更加合适一些.关于Drup