《C++程序设计原理与实践》读书笔记(三)

一个显示模型

一种图形及图形用户界面直接对应屏幕显示的思想。其基本概念先天就是图形化的(而且都是二维的,适应计算机屏幕的矩形区域),这些基本概念包括坐标、线、矩形和圆等。从编程的角度看,其目的是建立内存中的对象和屏幕图像的直接对应关系。

其基本模型如下:我们利用图形系统提供的基本对象(如线)组合出更复杂的对象;然后将这些对象添加到一个表示物理屏幕的窗口对象中;最后,用一个程序将我们添加到窗口上的对象显示在屏幕上,我们可以将这个程序看做屏幕显示本身,或者是一个“显示引擎”,或者是“我们的图形库”,或者“GUI库”,甚至将其看做“在屏幕背后进行画图工作的小矮人”,然后在屏幕上画出我们要添加到窗口的对象。

#include "Simple_windows.h"
#include "Graph.h"
int main()
{
    using namespace Graph_lib;
Point tl(100,100);
Simple_windows win(tl, 600,400, "Canvas");
Polygon poly;
poly.add(Point(300,200));
poly.add(Point(350,100));
poly.add(Point(400,200));
poly.set_color(Color::red);
win.attach(poly);
win.wait_for_button();
}

坐标系

计算机屏幕是一个由像素组成的矩形区域,像素是一个可以设置为某种颜色的点。在程序中,最常见的方式就是将屏幕建模为由像素组成的矩形区域,每个像素由x(水平)坐标和y(垂直)坐标确定。最左端的像素的x坐标为0,向右逐步递增,直到最右端的像素为止:最顶端的像素y坐标为0,向下逐步递增,直到最底端的像素为止。注意,y坐标是“向下增长”的。这可能有点奇怪,特别是对数学家而言。但是,“屏幕(窗口)大小各异,左上角可能是不同屏幕的唯一共同之处了,因些将其设定为原点。

按照惯例,main()函数包含我们要(直接或间接)执行的代码及例外处理:

int main()
{
   try
   {
       //... here is our code...
   }
   catch(exception& e)
   {
       // some error reporting
   return 1;
   }
   catch(...)
   {
       // some more error reporting
   return 2;
   }
}

为了使此main()编译能过,我需要定义exception。如果像往常一样包含了头文件std lib facilities.h或者直接包含标准库头文件<stdexcept>,就会获得exception的定义。

坐标轴

Axis xa(Axis::x, Point(20,300),280,10, "x axis"); 
win.attach(xa);
win.set_label("Canvas #2");
win.wait_for_button();

具体操作步骤为:创建坐标轴对象,将其添加到窗口,最后进行显示,如右图所示。可以看到,Axis::x是一条水平线,其上有指定数量(10个)的刻度和一个标签"x axis"。通常,标签用于解释坐标轴和刻度的含义。

绘制函数图

现在,我们已经有了一个包含坐标轴的窗口,因此看起来画出一个函数是个好主意。我们创建一个形状来表示正弦函数,并将它添加到窗口:

function sine(sin, 0, 100, Point(20,150),1000,50,50);
win.attach(sine);
win.set_label("Canvas #4");
win.wait_for_button();

在这段代码中,名为sine的function对象使用标准库函数sin()产生的值绘制一条正弦曲线。

Polygon函数图是表示数据的一种方法。Polygon(多边形)描述为一个点的序列,这些点通过线连接起来就构成Polygon类。第一条线连接第一个点到第二个点,第二条线连接第二个点到第三个点......最后一条线连接最后一个点到第一个点:

sine.set_color(Color::blue);
Polygon poly;
poly.add(Point(300,200));
poly.add(Point(350,100));
poly.add(Point(400,200));
poly.set_color(Color::red);
poly.set_style(Line_style::dash);
win.attach(poly);
win.set_label("Canvas #5);
win.wait_for_button();

屏幕是矩形,窗口是矩形,一张纸也是一个矩形。实际上,现实世界中很多形状都是矩形(或者至少是圆角矩形),原因在于矩形是最容易处理的形状。

Rectangle r(Point(200,200),100,50);

填充

前面绘制形状都是绘制轮廓,我们也可以使用某种颜色“填充”形状:

r.set_fill_color(Color::yellow);
poly.set_style(Line_style(Line_style::dash,4));

任何封闭的形状都可以填充。矩形很特殊,它非常容易填充。

文本

最后,任何一个绘图系统都不可能完全没有简单的文本输出方式 --将每个字符看做线的集合来绘制,并保证不会剪切掉字符。

Text t(Point(150,150), "Hello, graphical world!");

利用此例中的基本图形元素,你可以生成任何复杂、微妙的显示效果。请注意本章所有代码的一个共同特点:没有循环和选择语句,而且所有数据都是“硬编码的”。输出内容只是基本图形元素的简单组合。一旦我们开始使用数据和算法来组合这些基本图形,就可以得到更复杂、更有趣的输出效果了。

我们还可以从文件中加载图片:

Image ii(Point(100,50), "image.jpg");

基类和派生类

让我们从一个更为技术性的角度来观察基类和派生类。当设计一个图形接口库时,我们依赖以下3个关键的语言机制:

(一)派生(derivation):从一个类构造另一个类的方法,使新构造的类可以替换原来的类。派生类除了自己的成员外,还包括基类的所有成员。这通常称为继承,因为派生类“继承”了其基类的所有成员。在某些上下文环境中,派生类称为子类,而基类称为父类。

(二)虚函数(virtual function):在基类中定义一个函数,在派生类中有一个类型和名称完全一样的函数,当用户调用基类函数时,实际上调用的是派生类中的函数。

(三)私有和保护成员(Private and protected member):我们保持类的实现细节为私有的,以保护它们不被直接访问,简化维护操作,这通常称为封装。

继承、运行时多态和封装的使用,实际上就是面向对象程序设计最常见的标志。因此,除了其他的程序设计网络之外,C++还直接支持面向对象程序设计。

对象布局

对象在内在中是如何布局的呢。一个类的成员定义了对象的布局:数据成员在内存中一个接一个地存储。当使用继承时,派生类的数据成员被简单地放在基类的成员之后。

类的派生和虚函数的定义

我们通过在类名后给出一个基类来指定一个类为派生类。

struct Circle::Shape { /*....*/};

默认情况下,结构体(struct)的成员都是公有的。基类中的公用成员也会成为结构体的公有成员。另一种等价的定义方式如下:

class Circle:public Shape {public:/*......*/};

一个虚函数必须在类的声明中被声明为virtual,但是如果你把函数定义放在类外,关键字virtual就不必且不能出现在那里了。例如:

struct Shape
{
   //...
   virtual void draw_lines() const;
   virtual void movd();
   //...
};
virtual void Shape::draw_lines() const {/**.../} //error
void Shape::move() {/*...*/}  //OK

当你希望覆盖一个虚函数时,必须使用与基类中完全相同的名字和类型。例如:

struct Circle: Shape {
    void draw_lines(int) const;
void drawlines() const;
void draw_lines();
//...
}

访问

C++为类成员访问提供了一个简单的模型。类的成员可以是:

(一)私有的:如果一个成员是私有的,它的名字只能被其所属类的成员使用。

(二)受保护的(protected):如果一个成员是受保护的,它的名字只能被其所属类及其派生类的成员使用。

(三)公有的(public):如果一个成员是公有的,它的名字可以被所有函数使用。

纯虚函数

一个抽象类是一个只能作为基类的类。我们使用抽象类来表示那些抽象的概念,即相关实体共性的一般化所对应的那些概念。在程序中,抽象类通常定义了一组相关类(类层次)的接口。

时间: 2024-10-27 13:12:15

《C++程序设计原理与实践》读书笔记(三)的相关文章

世界是数字(读书笔记)

<世界是数字的>是世界顶尖计算机科学家Brian W.Kernighan写的一本计算机科普类读物,简明扼要但又深入全面地解释了计算机和通信系统背后的秘密,适合计算机初学者和非计算机专业的人读.这真的是一本好书,借Google常务董事长的话: 对计算机.互联网及其背后的奥秘充满好奇的人们,这绝对是一本不容错过的好书. 对于一个计算机已经学了N年的专业人士来说,这本书也许简单了点,不过我还是认真过了一遍,发现也有一定的收货,因为一个人很难掌握本领域里的所有知识,或多或少会有一些欠缺,总会有一些你以

&lt;世界是数字的&gt;读书笔记

<世界是数字的>读书笔记 <我是一只IT小小鸟>还余温未凉,老师就给我们介绍了新书名为<世界是数字的>.刚开始看这书名觉得世界是数字化的不是很正常嘛,新世纪新时代当然要有新改革,现代市场早就已经被数字产品给占领了,像笔记本电脑,数码相机等高科技产品在21世纪都是,屡见不鲜,不足为奇了.但是看完这本<世界是数字的>后,我发现我对数字化的世界还是停留在一知半解的地步. 第一章问我们计算机里有什么?计算机里有什么,我的第一反应就是鼠标键盘啊,这么想的肯定不止我一个

《世界是数字的》读书笔记 三

<世界是数字的>读书笔记 三 第六章 软件系统 操作系统是软件中的基础层,他负责管理计算机硬件,并为其他被称作应用程序的程序运行提供支持. 6.1操作系统 操作系统控制和分配计算机资源.首先,他负责管理CPU,调度和协调当前运行的程序.操作系统通常都需要管理数十个同时运行的进程或任务. 其次,操作系统管理RAM.他把程序加载到内存中以便执行指令. 最后,操作系统管理和协调外接设备的活动. 6.2操作系统怎么工作 计算机启动时首先要加载代码,加载的过程中还要检查硬件,比如哪些设备已经接入电脑,,

悟道—位IT高管20年的职场心经(读书笔记三)

悟道--一位IT高管20年的职场心经 第三章 世事洞明皆学问 职场就是你的大半个世界 是你一辈子也读不完的一大本书 想明白一个道理, 看明白一件事儿, 你就向成功迈进了一步. 1.1  "四行"说 四行是指: 第一,  你自己得行.自己的基础的能力是必须的,得靠自己学习. 第二,  得有人说你行.需要有伯乐,实际上是你得有一个自己的圈子,并且这些人都人认同你. 第三,  说你行的人得行.自己周围的圈子,里面也必须有牛人,只有在牛人的范围内,才能突显你自己的才能. 第四,  你身子骨得行

《你必须知道的.NET》读书笔记三:体验OO之美

一.依赖也是哲学 (1)本质诠释:"不要调用我们,我们会调用你" (2)依赖和耦合: ①无依赖,无耦合: ②单向依赖,耦合度不高: ③双向依赖,耦合度较高: (3)设计的目标:高内聚,低耦合. ①低耦合:实现最简单的依赖关系,尽可能地减少类与类.模块与模块.层次与层次.系统与系统之间的联系: ②高内聚:一方面代表了职责的统一管理,一方面又代表了关系的有效隔离: (4)控制反转(IoC):代码的控制器交由系统控制而不是在代码内部,消除组件或模块间的直接依赖: (5)依赖注入(DI): ①

《R实战》读书笔记三

第二章  创建数据集 本章概要 1探索R数据结构 2使用数据编辑器 3数据导入 4数据集标注 本章所介绍内容概括如下. 两个方面的内容. 方面一:R数据结构 方面二:进入数据或者导入数据到数据结构 理解数据集 一个数据集通常由一个表格组合而成,行表示观测,列表示变量.病人的数据集如表1所示. 表1 病人数据集 数据集能够反映数据结构.数据类型和内容. 数据结构 R数据结构如图2所示. 图2:R数据结构 数据结构即数据的组织方式,R数据结构包括向量.矩阵.数组.数据框和列表等. R向量 R向量是一

《大型网站技术架构》读书笔记三:大型网站核心架构要素

一.性能—响应时间决定用户 (1)浏览器端: ①浏览器缓存: ②使用页面压缩: PS:Gzip压缩效率非常高,通常可以达到70%的压缩率,也就是说,如果你的网页有30K,压缩之后就变成了9K左右.想要启用Gzip压缩,提高浏览速度,可以浏览这篇文章:http://www.chinaz.com/web/2012/1017/278682.shtml ③合理布局页面: CSS:把样式表置于顶部:避免使用CSS表达式(expression_r):使用外部JavaScript和CSS:削减JavaScri

Struts2技术内幕 读书笔记三 表示层的困惑

表示层能有什么疑惑?很简单,我们暂时忘记所有的框架,就写一个注册的servlet来看看. index.jsp <form id="form1" name="form1" method="post" action="loginServlet"> <table width="357" border="0" align="center"> <t

《淘宝技术这十年》读书笔记 (三). 创造技术TFS和Tair

前面两篇文章介绍了淘宝的发展历程和Java时代的变迁: <淘宝技术这十年>读书笔记 (一).淘宝网技术简介及来源 <淘宝技术这十年>读书笔记 (二).Java时代的脱胎换骨和坚若磐石 马云说过"创新不是为了与对手竞争,而是跟明天竞争",所以这篇文章讲述淘宝的创新技术TFS和Tair及创新的产品. 该篇文章不仅仅对在读大学生非常有所帮助,因为你能从文章中看到很多你需要学习的知识,不仅仅包括数据库.计算机网络.操作系统.数据结构等基础课程:还根据时代的技术变迁讲述了

《算法导论》读书笔记(三)

本章介绍了快速排序及其算法分析,快速排序采用的是分治算法思想,对包含n个数的输入数组,最坏情况下运行时间为θ(n^2),但是平均性能相当好,期望的运行时间为θ(nlgn).另外快速排序能够就地排序(我理解是不需要引入额外的辅助空间,每次划分能确定一个元素的具体位置),在虚拟环境中能很好的工作. 1.快速排序的描述 快速排序算法采用的分治算法,因此对一个子数组A[p-r]进行快速排序的三个步骤为: (1)分解:数组A[p...r]被划分为两个(可能为空)子数组A[p...q-1]和A[q+1...