文档库 最新最全的文档下载
当前位置:文档库 › CDC类的主要绘图成员函数

CDC类的主要绘图成员函数

CDC类的主要绘图成员函数
CDC类的主要绘图成员函数

CDC类的主要绘图成员函数

CDC类中常用绘图函数

1)绘制像素函数

原型:COLORREF SetPixel(int x,int y,COLORREF crColor );

设置某像素点的RGB值

2)获取像素颜色函数

原型:COLORREF GetPixel(int x,int y)const;

返回值:指定像素的RGB值。

参数说明:得到指定像素的RGB颜色值

一、画笔函数

画笔是用来绘制直线、曲线或图形的边界线,是绘图工具类之一

画笔通常具有线型、宽度和颜色三种属性

画笔的线型通常有实线、虚线、点线、点划线、双点划线、不可见线和内框架线7种,这些线型都是以PS_为前缀的预

定义标识符

默认的画笔是一个像素单位的黑色实线

要想更换画笔,可以在创建新画笔对象后,将其选入设备上下文,就可使用新画笔进行绘图。

1)创建画笔函数

原型:BOOL CreatePen(int nPenStyle,int nWidth,COLORREF crColor);

返回值:非零。

参数说明:

第一个参数nPenStyle是画笔的风格代码

第二个参数nWidth是画笔的宽度

第三个参数crColor是画笔的颜色。

PS_SOLID;实线;宽度任意指定

PS_DASH;虚线;宽度1(不可任意指定)

PS_DOT;点线;宽度1(不可任意指定)

PS_DASHDOT;点划线;宽度1(不可任意指定)

PS_DASHDOTDOT;双点画线;宽度1(不可任意指定)

PS_NULL;不可见线;宽度1(不可任意指定)

PS_INSIDEFRAME;内框架线;宽度任意指定

2)选择画笔函数

原型:Cpen *SelectObject(Cpen *pPen);

返回值:被替代画笔的指针。

参数说明:参数pPen是Cpen类的被选中的新画笔对象指针。本函数把原画笔换成新画笔,同时返回指向原画笔的指针。

3)删除画笔函数

原型:BOOL DeleteObject( );

返回值:非零。

参数说明:画笔使用完毕,把已成自由状态的画笔从系统内存中清除。

4)选择一支库画笔函数

原型:

virtual CGdiObject *SelectStockObject(int nIndex);

返回值:被替代的CGdiObject类对象的指针。

参数说明:参数nIndex是库笔代码

Windows系统中准备了一些使用频率较高的画笔,不需要创建,可以直接选用。同样,使用完库画笔时也不需要调用

DeleteObject()函数从内存中删除已使用过的画笔。

三种常用库笔:BLACK_PEN宽度为1的黑笔实线笔;WHITE_PEN宽度为1的白笔实线笔;NULL_PEN透明笔

二、画刷函数(图形内部进行填充)

1)创建实体画刷函数

BOOL CreateSolidBrush(COLORREF crColor );

选择画刷函数

2)CBrush *SelectObject(CBrush *pBrush );

删除画刷函数

3)BOOL DeleteObject( );

创建阴影画刷函数

4)BOOL CreateHatchBrush(int nIndex,COLORREF crColor);

第一个参数nIndex是阴影样式代码

第二个参数crColor是阴影线的颜色

5)选择一只库画刷函数

virtual CGdiObject *SelectStockObject(int nIndex);

参数:LTGRAY_BRUSH:亮灰色画刷;BLACK_BRUSH黑色画刷;NULL_BRUSH:空画刷(相当于HOLLOW_BRUSH);WHITE_BRUSH:白色画刷;DKGRAY_BRUSH 深灰色画刷;GRAY_BRUSH灰色画刷;HOLLOW_BRUSH 中空画刷

三、绘制矩形函数

原型:BOOL Rectangle(int x1,int y1,int x2,int y2);

返回值:非零。

参数说明:该函数使用当前画刷填充矩形内部,并用当前画笔绘制矩形边界线。

CPen MyPen,* OldPen;

MyPen.CreatePen(PS_SOLID,1,RGB(0,0,255));

OldPen=pDC->SelectObject(&MyPen);

CBrush MyBrush,*OldBrush;

MyBrush.CreateSolidBrush(RGB(255,0,0));

OldBrush=pDC->SelectObject(&MyBrush);

pDC->Rectangle(100,100,600,300);//画矩形

pDC->SelectObject(OldPen); //画框线为蓝色

MyPen.DeleteObject();

pDC->SelectObject(OldBrush); //填充为红色

MyBrush.DeleteObject();

坐标映射:

MM_TEXT 每个逻辑单位等于一个设备像素,x向右为正,y向下为正

MM_HIENGLISH 每个逻辑单位为0.001英寸,x向右为正,y向上为正

MM_LOENGLISH 每个逻辑单位为0.01英寸,x向右为正,y向上为正

MM_HIMETRIC 每个逻辑单位为0.01mm,x向右为正,y向上为正

MM_LOMETRIC 每个逻辑单位为0.1mm,x向右为正,y向上为正

MM_TWIPS每个逻辑单位为一个点的1/20(一个点是1/72英寸),x向右为正,y向上为正

MM_ANISOTRPIC x,y 可变比例

MM_ISOTROPIC x,y 等比例

我们就可以通过调用CDC::SetMapMode(int nMapMode)来设置相应的映射模式。例如:若将映射模式设置为MM_LOMETRIC,那么不管在什么设备中调用上述语句,都将显示出20*20mm的方块。而MM_ISOTROPIC 映射模式下:纵横比总是1:1,也就是说,无论比例因子如何变化,圆总是圆的。但,MM_ANISOTROPIC 映射模式下,x和y的比例因子可以独立地变化,即圆可以被拉扁成椭圆形状。在映射模式MM_ANISOTROPIC 和MM_ISOTROPIC中,常常可以调用CDC::SetWindowExt(设置窗口大小)和CDC::SetViewportExt(设置视口大小)函数来设置所需要的比例因子。

“窗口”和“视口”的概念往往不易理解。所谓“窗口”,可以理解是一种逻辑坐标下的窗口,而“视口”是我们实际看到的那个窗口,也就是设备坐标下的窗口,根据“窗口”和“视口”的大小就可以确定x和y的比例因子,它们的关系如下:

x比例因子=视口x大小/窗口x大小

y比例因子=视口y大小/窗口y大小

四、绘制椭圆函数

原型:BOOL Ellipse(int x1,int y1,int x2,int y2);

返回值:非零。

参数说明:Ellipse函数中,参数x1,y1是限定椭圆范围的外接矩形左上角点的坐标;参数x2,y2是限定椭圆范围的外

接矩形右下角点的坐标

注意VC++中没有专门的画圆函数,只是把圆绘制为长半轴和短半轴相等的椭圆。Ellipse函数使用当前画刷填充椭圆内

部,并用当前画笔绘制椭圆边界线。

例将一个圆绘制在视区中央,圆的形状依据视区形状而定。当窗口的形状发生改变时,圆的形状也随之改变。坐标系

的中点位于屏幕中心,X轴向右,Y轴向上。圆的边界为一像素宽的蓝色边界线,内部填充为红色。

CRect Rect; //定义矩形对象

GetClientRect(&Rect); //获得当前窗口的客户区大小

pDC->SetMapMode(MM_ANISOTROPIC); //设置MM_ANISOTROPIC映射模式

pDC->SetWindowExt(Rect.Width(),-Rect.Height()); //设置窗口范围

pDC->SetViewportExt(Rect.right,-Rect.bottom); //设置视区范围

pDC->SetViewportOrg(Rect.right/2,Rect.bottom/2); //设置视口原点

CPen MyPen,*OldPen;

MyPen.CreatePen(PS_SOLID,1,RGB(0,0,255));

OldPen=pDC->SelectObject(&MyPen);

CBrush MyBrush,*OldBrush;

MyBrush.CreateSolidBrush(RGB(255,0,0));

OldBrush=pDC->SelectObject(&MyBrush);

pDC->Ellipse(-Rect.right/2, -Rect.bottom/2,Rect.right/2,Rect.bottom/2);

pDC->SelectObject(OldPen); //蓝边

MyPen.DeleteObject();

pDC->SelectObject(OldBrush); //填充红色

MyBrush.DeleteObject();

五、绘制多边形函数

BOOL Polygon(LPPOINT lpPoints,int nCount);

参数说明:

第一个参数lpPoints指定多边形顶点数组中每一个顶点是一个POINT结构或CPoint对象

第二个参数nCount指定多边形数组中的顶点个数

该函数用当前画笔绘制多边形边界线,用当前画刷填充多边形内部。

例绘制四个顶点分别位于视区上部中点、右部中点、下部中点和左部中点的菱形。边界线为蓝色,内部用红色填充

CRect Rect;

GetClientRect(&Rect); //获得客户区

CPen PenBlue(PS_SOLID, 5, RGB(0, 0, 255)); //定义粗蓝色画笔,绘制边界线

CPen* OldPen=pDC->SelectObject(&PenBlue); //选取画笔

CBrush BrushRed(RGB(255, 0, 0)); //定义红色画刷,填充多边形内部

CBrush* OldBrush = pDC->SelectObject(&BrushRed); //选取画刷

CPoint p[4]; //定义多边形顶点数组

p[0].x=Rect.left+Rect.Width()/2;

p[0].y=Rect.top; //计算顶部中点

p[1].x=Rect.right;

p[1].y=Rect.top+Rect.Height()/2; //计算右部中点

p[2].x=p[0].x;

p[2].y=Rect.bottom; //计算下部中点

p[3].x=Rect.left;

p[3].y=p[1].y; //计算左部中点

pDC->Polygon(p, 4);//绘制多边形

pDC->SelectObject(OldPen);//画笔勾边

pDC->SelectObject(OldBrush);//画刷填充

六、填充函数

void FillRect(LPCRECT lpRect,CBrush *pBrush);

参数说明:

第一个参数lpRect指定矩形,是一个Rect结构或CRect对象

第二个参数pBrush指定画刷对象指针。该函数将用当前画刷填充矩形内部,但不画边界线。

七、路径函数

⑴打开路径

BOOL BeginPath();

⑵关闭路径图

BOOL EndPath();

⑶填充路径

BOOL FillPath();

例绘制两个多边形,一个使用路径填充,另一个不使用路径填充,试观察结果的异同。

//绘制第一个多边形,用路径填充图

CPoint p[7]; //定义顶点数组

p[0]=CPoint(340,240);p[1]=CPoint(260,160);

p[2]=CPoint(220,260);p[3]=CPoint(260,370);

p[4]=CPoint(320,300);p[5]=CPoint(360,380);

p[6]=CPoint(440,220);

CBrush MyBrush;

MyBrush.CreateSolidBrush(RGB(255,0,0));

CBrush *OldBrush=pDC->SelectObject(&MyBrush);

pDC->BeginPath();

pDC->MoveTo(p[0]);//绘制多边形

for(int i=1;i<7;i++)

pDC->LineTo(p[i]);

pDC->LineTo(p[0]);

pDC->EndPath();

pDC->FillPath();

pDC->SelectObject(OldBrush);

MyBrush.DeleteObject();

//绘制第二个多边形,用画刷填充

p[0]=CPoint(740,240);p[1]=CPoint(660,160);

p[2]=CPoint(620,260);p[3]=CPoint(660,370);

p[4]=CPoint(720,300);p[5]=CPoint(760,380);

p[6]=CPoint(840,220);

MyBrush.CreateSolidBrush(RGB(255,0,0));

OldBrush=pDC->SelectObject(&MyBrush);

pDC->Polygon(p,7);

pDC->SelectObject(OldBrush);

MyBrush.DeleteObject();

八、位图函数

⑴导入位图

BOOL LoadBitmap(UINT nIDResource);//参数nIDResource是资源的ID编号

⑵建立与位图相应的内存设备上下文

virtual BOOL CreateCompatibleDC( CDC* pDC );

参数pDC是设备上下文的指针,用于在向屏幕输出图形前作准备。

⑶选择位图函数

CBitmap *SelectObject( CBitmap *pBitmap );

参数pBitmap是CBitmap类的被选中的新位图指针对象。把原位图换成新位图,同时返回指向原位图的指针。

⑷传送位图函数

BOOL BitBlt(int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, DWORD dwRop);

参数x,y是目标区域的左上角点坐标

参数nWidth和nHeight是目标区域的宽度和高度

参数pSrcDC是源设备上下文的指针

参数xSrc和ySrc是源位图的左上角点坐标

参数dwRop是光栅操作码

例如dwRop=SRCCOPY,表示将原位图直接拷贝到目标位图。

例在屏幕上显示一幅位图。

CRect Rect;//定义客户区

GetClientRect(&Rect);//获得客户区的大小

CDC MemDC;//定义一个内存设备上下文对象

CBitmap Bitmap,*OldBitmap; //定义一个CBitmap对象和一个CBitmap对象指针

Bitmap.LoadBitmap(IDB_BITMAP1); //从资源中导入图片

MemDC.CreateCompatibleDC(pDC); //建立与位图相应的内存设备上下文

OldBitmap=MemDC.SelectObject(&Bitmap); //在内存设备上下文选用位图图像

pDC->BitBlt(0,0,Rect.Width(),Rect.Height(),&MemDC,0,0,SRCCOPY); //将位图数据传送到屏幕

MemDC.SelectObject(OldBitmap); //将位图图像保存到内存中

九、图形文本函数

⑴文本颜色设置函数

原型:virtual COLORREFSetTextColor(COLORREF crColor);

返回值:原文本颜色的RGB值。

参数说明:指定文本颜色。

⑵文本背景颜色设置函数

原型:virtual COLORREFSetBkColor(COLORREF crColor);

返回值:原文本背景色的RGB值。

参数说明:指定文本背景颜色。

(3) 文本输出函数

原型:BOOL TextOut(int x,int y,const CString& str);

返回值:非零。

参数说明:参数x,y是文本的起点坐标,参数str是CString对象。

⑷文本格式函数

原型:void Format(LPCTSTR lpszFormat, ... );

返回值:无。

参数说明:参数lpszFormat是格式控制字符串,如%d、%f、%c等。本格式常用于输出数值型数据。

例在点(100,100)处输出黄底红字“Compute Graphics Based on VC++!”;在(300,100)输出“BoChuang

Research Institute”;在(100,130)整数(5,8);在(130,130)处输出小数(5.0,8.0)。

int a1=5,b1=8;

double a2=5.2,b2=8.3;

CString data, c="BoChuang Research Institute";

pDC->SetTextColor(RGB(255,0,0));

pDC->SetBkColor(RGB(255,255,0));

pDC->TextOut(100,100,"Compute Graphics Based on VC++!");//输出文本1

data.Format("%s",c);//输出文本2

pDC->TextOut(330,100,data);

data.Format("%d,%d",a1,b1);//输出整数

pDC->TextOut(100,130,data);

data.Format("%f,%f",a2,b2);//输出小数

pDC->TextOut(130,130,data);

例使用双缓冲机制在博创研究所位图上输出“博创研究所”文字。

CRect Rect; //定义客户区

GetClientRect(&Rect); //获得客户区的大小

CDC MemDC; //定义内存设备上下文

CDC Picture; //定义图片;

CBitmap Bitmap,*OldBitmap; //定义一个CBitmap对象和一个CBitmap对象指针

Bitmap.LoadBitmap(IDB_BITMAP1); //从资源中导入位图

MemDC.CreateCompatibleDC(pDC); //建立与位图相应的内存设备上下文

OldBitmap=MemDC.SelectObject(&Bitmap); //把内存设备上下文换成位图图像

MemDC.BitBlt(0,0,Rect.Width(), Rect.Height(),&Picture,0,0,SRCCOPY);

//将位图数据传送到内存设备上下文

MemDC.SetBkMode(TRANSPARENT); //设置文字背景透明

MemDC.SetTextColor(RGB(255,255,255)); //设置文字颜色为白色

MemDC.TextOut(500,350,"博创研究所"); //输出文字

pDC->BitBlt(0,0,Rect.Width(),Rect.Height(),&MemDC,0,0,SRCCOPY); //将内存数据传送到屏幕

MemDC.SelectObject(OldBitmap); //从内存设备上下文中释放位图图像

十、VC++绘制图形的几种方法

1)第一种方法:使用OnDraw成员函数

2)第二种方法:使用CDC *pDC的菜单调用方式

CDC *pDC=GetDC();

pDC->MoveTo(20,30);

pDC->LineTo(200,300);

ReleaseDC(pDC);

3)第三种方法:使用CClientDC dc(this)的菜单调用方式

CClientDC dc(this);

dc.MoveTo(20,30);

dc.LineTo(200,300);

不同点只是使用显示器客户区设备上下文类定义了客户区对象dc,并使用客户区的this指针对dc对象进行初始化,使dc对象指向显示器的客户区,这种方法不需要调用和释放设备上下文。

十一、几个例子

例1 改变窗口大小时,窗口会以三种不同的颜色显示窗口背景。

1)建一个单文档SDI应用程序,名为:显示背景颜色

2)在视图的头文件View.h的public下定义矩形窗口对象:CRect r;

3)在视图的执行文件View.cpp前面加颜色预定义:

#endif

#define RED RGB(255,0,0) //红色

#define GREEN RGB(0,255,0) //绿色

#define BLUE RGB(0,0,255) //兰色

#define BLACK RGB(0,0,0) //黑色值

/////////////////////////////////////////////////////////////////////////////

// CMyView

IMPLEMENT_DYNCREATE(CMyView, CView)

BEGIN_MESSAGE_MAP(CMyView, CView)

……….

4)在OnDraw()函数添加如下代码:

void CMyView::OnDraw(CDC* pDC)

{ CMyDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

GetClientRect(r); //获取窗口大小

if(r.right>750&&r.right<1000||r.bottom>750&&r.bottom<1000)

pDC->FillSolidRect(r,RED); //充填窗口背景红色

else if(r.right>500&&r.right<750||r.bottom>500&&r.bottom<750)

pDC->FillSolidRect(r,GREEN); //充填窗口背景绿色

else if(r.right<500||r.bottom<500)

pDC->FillSolidRect(r,BLUE); //充填窗口背景蓝色)

else

pDC->FillSolidRect(r,BLACK);//充填窗口背景黑色

}

5)运行后出现的窗口是红色,最小是蓝色,中间是绿色。

例2 绘制2个不同填充形式的五角星

(1)建一个单文档的应用程序,名为:五角星

(2)在视图类的实现文件(View.cpp)Draw函数中加下列代码:

void CMyView::OnDraw(CDC* pDC)

{ CMyDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

POINT pt[5]={{47,10},{30,90},{90,35},{10,30},{75,85}};//五角星的五个点

CBrush brush(HS_FDIAGONAL,RGB(255,0,0));//向上点斜线,红色

CBrush *oldbrush=pDC->SelectObject(&brush);

pDC->SetPolyFillMode(ALTERNATE);

pDC->Polygon(pt,5);

for(int i=0;i<5;i++)

pt[i].x +=80;//x+80第二个五星的点

pDC->SetPolyFillMode(WINDING);

pDC->Polygon(pt,5);

pDC->SelectObject(oldbrush);

brush.DeleteObject();

}

(3)编译运行,见图所示

说明:SetPolyFillMode(ALTERNATE):是CDC类的一个成员函数,用于设置填充模式,它的参数可以是ALTERNATE和WINDING。对於ALTERNATE方式,可以设想从一个无穷大的封闭区域内部的点画线,只有假想的线穿过了奇数条边界线时,才填入封闭区域。这就是填入了星的角而中心没被填入的原因。五角星的例子使得WINDING方式看起来比实际上更简单一些。在绘制单个的多边形时,大多数情况下,WINDING 方式会填入所有封闭的区域。但是也有例外。在WINDING方式下要确定一个封闭区域是否被填入,仍旧可以设想从那个无穷大的区域画线。如果假想的线穿过了奇数条边界线,区域就被填入,这和ALTERNATE 方式一样。如果假想的线穿过了偶数条边界线,则区域可能被填入也可能不被填入。如果一个方向的边界线数不相等,就填入区域。

例3:调色板的概念

在MFC中,Cpalette类封装了GDI调色板,它保存着系统可用的色彩信息,是应用程序和彩色输出设备上下文的接口。

由于显示真彩色位图需要大量的视频内存,一副640*480的真彩色图像需要约1MB的视频内存。因为数据量大增,显示真彩色影响到系统的整体性能。为了解决这个问题,计算机使用调色板来限制颜色的数目。调色板实际上是一个有256个表项的RGB颜色表,颜色表的每项是一个24位的RGB颜色值。使用调色板时,在视频内存中存储的不是24位的颜色值,而是调色板的4位或8位的索引。这样一来,显示器可以同时显示的颜色被限制在256色以内,对系统资源的耗费大大降低了。

也就是说,调色板预先为程序员准备了256种颜色,当需要制定某个像素的颜色时,只需要说明是调色板中的第几个颜色即可。因为调色板的颜色较少,那些在调色板中不存在的颜色,则去匹配最接近的。

调色板最多只能表示256色,所以,它主要是用于低档显示器的一种解决方案。虽然目前针对个人电脑来说,在很多情况下,对调色板的应用将逐渐减少。但由于大量显示器设备(比如手上电脑或者手机)还需要单色图、256色图、灰度图,所以调色板仍大有用武之地。

利用Windows提供的PALETTEINDEX宏可以指定调色板的某个索引所指定的颜色,可以使用操作系统的默认调色板,也可以自己创建个性化的调色板。

我们看一下系统缺省的调色板,该调色板只有20种保留颜色,如果要使用新的颜色,则应该创建一个新的逻辑调色板并将其选入到设备上下文中。但仅仅这样还不能使用新颜色,程序只有把设备上下文中的逻辑调色板实现到系统调色板中,新的颜色才能实现。

下面我们通过修改视图类的OnDraw函数,来获取系统默认调色板的所有索引项并显示出来。

利用MFC AppWizard(exe)创建一个单文档的应用程序,名为:调色板

在视图类的OnDraw函数中添加如下代码:

void CMyView::OnDraw(CDC* pDC)

{ CMyDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

CPalette m_Palette;

//显示调色板

CBrush brush,*pOldBrush;

int x,y;

pDC->SelectPalette(&m_Palette,FALSE);

pDC->RealizePalette();

pDC->SelectStockObject(BLACK_PEN);

for(int i=0;i<256;i++)

{ x=(i%16)*16;

y=(i/16)*16;

brush.CreateSolidBrush(PALETTEINDEX(i));//调色板索引引用

pOldBrush=pDC->SelectObject(&brush);

pDC->Rectangle(x,y,x+16,y+16);

pDC->SelectObject(pOldBrush);

brush.DeleteObject();

}

}

编译运行,结果如显示的调色板。

十二、颜色和颜色对话框

一个彩色像素的显示需要颜色空间支持,MFC中的CDC类使用的是RGB颜色空间,即选用红(R)、绿(G)、蓝(B)3种基色分量,通过对这3种基色不同比例的混合,可以得到不同彩色效果。在MFC中使用COLORREF 数据类型来表示一个32位的RGB颜色,它可以用16进制表示:OxOObbggrr。其中:rr,gg,bb分别表示红、绿、蓝各种颜色分量的16进制值,最大为Oxff。在具体操作RGB颜色时,还可使用下列宏操作:GetBValue 获得32位RGB颜色值中的蓝色分量

GetGValue 获得32位RGB颜色值中的绿色分量

GetRValue 获得32位RGB颜色值中的红色分量

RGB 将指定的R,G,B分量值转换成一个32位的RGB颜色值

MFC的CColorDialog类为应用程序提供了“颜色选择通用”对话框,如图12.1所示。

CColorDialog类具有下列的构造函数:

CColorDialog(COLORREF clrInit=0, DWORD dwFlags=0, CWnd *pParentWnd=NULL);

参数:

clrInit 用于指定选择的默认颜色值,若此值没有指定,则为RGB(0,0,0) (黑色)

pParentWnd 用于指定对话框的父窗口指针

dwFlags

用于表示定制对话框外观和功能的系列标志参数,

它可以是下列值之一或“|”组合:

CC_ANYCOLOR 在基本颜色单元中列出所有可得到的颜色

CC_FULLOOEN 显示所有的颜色对话框界面。图12.1“颜色选择通用”对话框(调色板)若此标志没有被设定,则用户单击“规定自定义颜色”按钮才能显示出定制颜色界面。

CC_PREVENTFULLOPEN禁用“规定自定义颜色”按钮

CC_SHOWHELP 在对话框中显示“帮助”按钮

CC_SOLIDCOLOR 在基本颜色单元中只列出所得到的纯色。

当对话框“OK”退出(即DoModal返回IDOK)时,可调用下列成员获得相应的颜色:

COLORREF GetColor()const; //返回用户选择的颜色

void SetCurrentColor(COLORREF clr); //强制使用clr作为当前选择的颜色

static COLORREF *GetSavedCustomColors(); //返回用户自己定义的颜色

例使用颜色对话框,可在窗口中随意画图、更改颜色及画笔宽度、填充颜色等。(颜色、工具条、鼠标) 如何进行颜色选取,MFC为我们封装了一个名为CColorDialog的类,这个类将使我们轻松地完成颜色选取,弹出颜色对话框,“自定义颜色”等。

(1)建一个单文档SDI应用程序,名为:工具条绘图

(2)在查看的下面建菜单:ID为:ID_COLORS_MENU ,标题为:画笔(&H)

(3)加工具条及工具条按钮,样式如图12.2所示:

图12.2 工具条按钮布置的样式

ResourceView→右键击Toolbar→Insert→Toolbar→New,将此工具条本身的ID改为:IDR_MYTOOLBAR,右边工具条上出现一个按钮,双击这个按钮,将其ID改为:ID_BUTTONRED,之后用画刷将其涂成红色。再逐个双击后面出现的空白按钮,将它们逐个的ID改为:

ID_BUTTONGREEN(用画刷涂成绿色)

ID_BUTTONBLUE(用画刷涂成蓝色)

ID_BUTTONDASH(细斜杠)

ID_BUTTONSOLID(粗斜杠)

ID_BUTTONRECT(方框填充)

ID_BUTTONFILL(画刷图形)

ID_BUTTON_PENCOLORS(画笔图形)

ID_BUTTON_PENWILD(画笔宽度)

(4)加鼠标映射(分别映射到视图View里)

WM_ LBUTTONDOWN 鼠标按下

WM_MOUSEMOVE 鼠标移动

WM_LBUTTONUP 鼠标抬起

(5)自定义按钮的消息映射函数:用于选择其中的任何一项画图:

在视图头文件(View.h)消息映射区里加:afx_msg void OnPenChioce(UINT nID);

(6)在视图执行文件(View.cpp)消息映射开始处加:

//位图按钮消息映射函数

ON_COMMAND_RANGE(ID_BUTTONRED,ID_BUTTON_PENWILD,OnPenChioce)

(7)在视图Wiew.h头文件的public:下加成员变量和函数:

CPoint StartPt, EndPt; //用于记录画笔的起始位置和终点位置

CPen Pen; //画笔对象

COLORREF m_colors; //颜色对象

CRect Rect; //矩形对象即窗口大小

int PenStarte; //画笔状态

DWORD PenStyle; //用于存储画笔风格

int MyPenWild; //用于设置画笔的宽度

void FillMyRect(); //充填颜色

void MyColorsDlg(); //用以完成颜色选取对话框的实现

void WildDlg(); //用于完成选择画笔宽度对话框的初始化

(8)在视图View.cpp的开头部分加:

#define RED RGB(255,0,0)

#define GREEN RGB(0,255,0)

#define BLUE RGB(0,0,255)

在下面的构造函数里这样加:

CMyView::CMyView()

:PenStarte(0) //此处的“:”表示其后面列表称为成员初始化列表。画笔状态初始为0

{ MyPenWild=1; //用于设置画笔的宽度,初始宽度为1

PenStyle=PS_SOLID; //用于存储画笔风格,初始风格为实线

}

(9)在MainFrm.h的public:里加:

CToolBar *m_pColorToolbar;//定义颜色工具条类指针

(10)在MainFrm.cpp里的构造函数里这样加:

CMainFrame::CMainFrame():m_pColorToolbar(0)

{ // TODO: add member initialization code here

}

说明:“:”表示其后面列表称为成员初始化列表。这里表示:颜色工具条类指针对象初始状态为0。(11)为该项目增加一对话框:Insert→Resource(或Ctrl+R)→Dialog→New

1)将对话框本身的ID改为:IDD_DIALOG_WILD

2)拖过来Edit Box改ID为:ID_EDIT_WILD

注意:属性General里置好Visible和Tab Stop

3)拖来一个Spin旋转按钮控件放在EDIT右边;改ID为:IDC_SPIN_WILD 同样置好Visible和Tab Stop,

在Styles下:Orientation(控件放置方向)栏置Vertical(垂直),在Alignment(控件在伙伴窗口的位置安排)栏置好Right(右边),右边置好Auto buddy(自动选择前一个窗口作为伙伴窗口)和Set buddy integer (使控件设置伙伴窗口,数值可十进制或十六进制)及Arrow keys(当按下向上和向下方向键时,也能增加或减少)

(12)给对话框加类

View→ClassWizard→AddClass(或你双击对话框,问你要加新类吗,回答:“是”就行了)。在出现的

对话框的Name栏写:CPENWILDDLG,基类:CDialog;下面保证是IDD_DIALOG_WILD。

为对话框类上的控件加成员变量:

IDC_EDIT_WILD int m_penwild //整型

IDC_EDIT_WILD CEdit m_cpenwild //编辑类型

IDC_SPIN_WILD CSpinButtonCtrl m_cwildspin //旋转按钮

注:可在对话框类PENWILDDLG.cpp的DDX下面加:DDV_MinMaxInt(pDX,m_penwild,1,100);

在视图头文件View.h里加:#include “PENWILDDLG.h”

(13)加映射消息及代码:

1)将菜单项消息映射ID_COLORS_MENU映射在CMainFrame主框架中并加代码:

void CMainFrame::OnColorsMenu()

{ if(0==m_pColorToolbar)

{ m_pColorToolbar = new CToolBar; //为颜色工具条开辟一片单元

m_pColorToolbar->Create(this); //建一个Windows工具条并将其连接到此CTollBar中

m_pColorToolbar->LoadToolBar(IDR_MYTOOLBAR);//加载资源编辑器创建的工具条资源(已建好的工具条)

m_pColorToolbar->EnableDocking(CBRS_ALIGN_ANY);

DockControlBar(m_pColorToolbar);

}

}

说明:EnableDocking(CBRS_ALIGN_ANY):可使控制条停靠在父窗口的任何一边

参数:指定框架窗口的哪一边可用做控制条的停靠点,可以是下列值中一个或多个:CBRS_ALIGN_TOP允许停靠在客户区的顶部

CBRS_ALIGN_BOTTOM允许停靠在客户区的底部

CBRS_ALIGN_LEFT允许停靠在客户区的左边

CBRS_ALIGN_RIGHT允许停靠在客户区的右边

CBRS_ALIGN_ANY允许停靠在客户区的任何一边

CBRS_ALIGN_MULTI允许一个小框架窗口中存在多个浮动控制条

2)在主框架为ID_COLORS_MENU加映射消息UPDATE_COMMAND_UI(命令属性)

void CMainFrame::OnUpdateColorsMenu(CCmdUI* pCmdUI)

{ if (0 == m_pColorToolbar)

pCmdUI->SetCheck(FALSE);

else

if(m_pColorToolbar->IsWindowVisible() == TRUE)

pCmdUI->SetCheck(TRUE);

else

pCmdUI->SetCheck(FALSE);

}

说明:

1、SetCheck:设置命令用户界面元素为恰当选择状态,可用于工具条按钮(不确定状态)和菜单项。

参数:0:即FALSE设置为不选择;1:即TRUE设置为选择;2:设置为不确定

2、IsWindowVisible:获得给定窗口的可视状态。

函数原型:BOOL IsWindowVisible(HWND hWnd);

参数; hWnd:被测试窗口的句柄。

3、CCmdUI:仅用于ON_UPDATE_COMMAND(不是命令)处理函数中,一般用来设置特性等用。如:pCmdUI->Enable(false);

是屏蔽菜单

3)为鼠标按下消息(视图类中View)加代码:

void CMyView::OnLButtonDown(UINT nFlags, CPoint point)

{ CRect r;

if(PenStarte==0)

{ StartPt.x=point.x; //起始位置的x坐标

StartPt.y=point.y; //起始位置的y坐标

}

else if(PenStarte==1)

{

Rect.left=point.x; //窗口左x坐标

Rect.top=point.y; //窗口顶y坐标

}

else{}

CView::OnLButtonDown(nFlags, point);

}

为鼠标抬起消息(视图类中View)加代码:

void CMyView::OnLButtonUp(UINT nFlags, CPoint point)

{ if(PenStarte==0) //画笔状态为0

StartPt.x=-1; //起始位置x

else if(PenStarte==1) //画笔状态为1

{ Rect.right=point.x;

Rect.bottom=point.y;

CDC *pDC=GetDC();

CPen RectPen(PS_DASH,1,m_colors);

pDC->SelectObject(&RectPen); //选择一个GDI绘图对象

pDC->MoveTo(Rect.left,Rect.top);

pDC->LineTo(Rect.right,Rect.top);

pDC->LineTo(Rect.right,Rect.bottom);

pDC->LineTo(Rect.left,Rect.bottom);

pDC->LineTo(Rect.left,Rect.top);

ReleaseDC(pDC);

PenStarte=0;//画笔状态置0

}

CView::OnLButtonUp(nFlags, point);

}

说明:

1、GetDC:检索一指定窗口的客户区域或整个屏幕的显示设备上下文的句柄;以后可以在GDI函

数中用该句柄绘图。函数原型为:GetDC(HWND hWnd);

参数:hWnd为检索的窗口的句柄,若为NULL,则检索整个屏幕的设备上下文环境。

2、CPen RectPen(PS_DASH,1,m_colors):定义画笔对象;虚线、宽度为1、含有颜色值。

函数原型为:CPen(int nPenStyle,int nWidth,COLORREF crColor)

3、SelectObject:将一个对象选入设备环境中,新选对象竟替代同一类型的先前对象,函数原型为:

CPen *SelectObjiect(CPen *pPen)

4、MoveTo:将当前位置移动到x和y参数(或point参数MoveTo(POINT point))指定的点,函数为:MoveTo(int x,int y)

5、LineTo:从当前位置到由x和y(或point)指定的端点(但不包括此端点)画线:BOOL LineTo(int x,int y)

6、ReleaseDC:释放设备上下文环境(DC)供其他应用程序使用。函数的效果与设备上下文环境类型有关。它只释

放公用的和设备上下文环境,对于类或私有的则无效,函数原型为:int ReleaseDC(HWND hWnd, HDC hdc);

参数:

hWnd:指向要释放的设备上下文环境所在的窗口的句柄。

hdc:指向要释放的设备上下文环境的句柄。

5)为鼠标移动消息(视图类中View)加代码:

void CMyView::OnMouseMove(UINT nFlags, CPoint point)

{ CClientDC dc(this);

dc.SelectObject(&Pen);

EndPt.x=point.x; //终点x坐标

EndPt.y=point.y; //终点y坐标

if(StartPt.x>=0) //起始x坐标大于0

{ dc.MoveTo(StartPt.x,StartPt.y);//从起点画线

dc.LineTo(EndPt);//到指定的端点画线

StartPt.x=EndPt.x;//端点x再当起点x

StartPt.y=EndPt.y; //端点y再当起点y

}

CView::OnMouseMove(nFlags, point);

}

说明:

CClientDC dc(this):构造CClientDC对象,则设备环境的映射区域限于客户区域,不能在客户区域外绘图。原点(0,0)在客户区左上角。this 是一个指向CMyView对象的指针。如果创建CWindowDC对象,则设备环境的映射区域为整个窗口(包括标题栏、状态栏、窗口边框等)。原点(0,0)在整个窗口的左上角。

注意:

1、视图窗口没有非客户区域

2、视图窗口覆盖在框架窗口之上

完成自定义充填函数(View)加代码(全用手写):

void CMyView::FillMyRect()

{ CDC *pDC=GetDC();

CBrush Brush; //画刷

Brush.CreateSolidBrush(m_colors); //用指定实颜色初始化画刷。参数:画刷颜色

pDC->FillRect(&Rect,&Brush);

ReleaseDC(pDC);// 释放设备上下文环境(DC)供其他应用程序使用

}

说明:FillRect(&Rect,&Brush):用给定画刷填充指定矩形,包括左边和上部边界,但不填充右边和底部边界

完成自定义颜色选取对话框的实现(View)函数代码(全用手写) :

void CMyView::MyColorsDlg()

{ CColorDialog dlg; //颜色对话框类对象

if(IDOK==dlg.DoModal())

{ m_colors=dlg.GetColor();

Pen.DeleteObject();//删除GDI对象,对象使用的所有系统资源都会被释放

Pen.CreatePen(PenStyle,1,m_colors);

}

}

说明:GetColor:在调用DoModal之后调用,用以获取用户选中颜色的信息。返回值:一个COLORREF值,其中包括颜色对话框中选中的颜色的RGB信息。

8)完成自定义选择画笔宽度对话框的初始化(View)函数代码(全用手写):

void CMyView::WildDlg()

{ CPENWILDDLG Dlg;

if(IDOK==Dlg.DoModal())

MyPenWild=Dlg.m_penwild;

}

完成自定义按钮的消息映射(View)函数加代码(全用手写):

void CMyView::OnPenChioce(UINT nID)

{ switch(nID)

{ case ID_BUTTONRED:m_colors=RED;break;

case ID_BUTTONGREEN:m_colors=GREEN;break;

case ID_BUTTONBLUE:m_colors=BLUE;break;

case ID_BUTTONDASH:PenStyle=PS_DASH;break;

case ID_BUTTONSOLID:PenStyle=PS_SOLID;break;

case ID_BUTTONRECT:PenStarte=1;break;

case ID_BUTTONFILL:FillMyRect();break;

case ID_BUTTON_PENCOLORS:MyColorsDlg();break;

case ID_BUTTON_PENWILD:WildDlg();break;

}

Pen.DeleteObject();

Pen.CreatePen(PenStyle,MyPenWild,m_colors);

}

(14)编译运行,如图12.3和12.4 所示。

图12.3画线和填充色、弹出调色板设置颜色

图12.4 画笔宽度为20绘制的粗线十三、使用字体对话框

成员函数、非成员函数和友元函数介绍

成员函数、非成员函数和友元函数介绍 一、成员函数、非成员函数和友元函数 成员函数和非成员函数最大的区别在于成员函数可以是虚拟的而非成员函数不行。 成员函数的优势是能够方便的进行动态绑定,实现多态。 说明一个函数为一个类的友元函数则该函数可以访问此类的私有数据和方法。 二、成员函数介绍 1、显式构造函数 C++中的e xplicit关键字用来修饰类的构造函数,表明该构造函数是显式的。 隐式构造函数能够实现将该构造函数对应数据类型的数据转换为该类对象。 class MyClass { public: MyClass( int num); } MyClass obj = 10; //ok,convert int to MyClass 如果在构造函数前加上关键字explicit,上述编译出错。 2、静态函数: 类中,static型的成员函数,由于是类所拥有的,而不是具体对象所有的。 静态函数屏蔽了this指针,因此,如果成员函数作为回调函数,就应该用static去修饰它。 3、虚函数: 虚函数首先是一种成员函数,它可以在该类的派生类中被重新定义并被赋予另外一种处理功能。 注意多态不是函数重载。函数重载属于静态绑定,虚函数实现多态是动态绑定。 4、纯虚函数: 在抽象类中定义纯虚函数,必须在子类实现,不过子类也可以只是声明为纯虚函数,由 子类的子类实现。 5、协变返回类型: 一般来说,一个重写的函数与被它重写的函数必须具有相同的返回类型。 这个规则对于”协变返回类型(covariant return type)”的情形来说有所放松. 也就是说,若B是一个类类型,并且一个基类虚拟函数返回B *,那么一个重写的派生类函数可以返回D *, 其中的D公有派生于B(即D是一个(is-a)B).若基类虚函数返回B &,那么一个重写的派生类函数可以返回一个D&. 考虑如下一个shape层次结构的clone操作: Class Shape { Public: //… Virtual Shape *clone () const = 0; //prototype(原型) //… }; Class Circle : public Shape {

C++课设:简单画图程序

简单画图程序 1.基本功能描述 本次课程设计的任务是利用计算机和VC开发环境编写一个简单画图程序,该程序的设计指标(即主要功能)有:①用鼠标拖动绘制圆、椭圆、矩形,线等基本图形;②能控制画笔的线宽和颜色;③能对图形进行颜色填充;④在鼠标移动的过程中能实时显示当前绘制的图形。 除了以上几点功能,我有另外添加了工具栏、铅笔、橡皮等功能来使程序更方便地让用户使用,简化了人机交互的过程。 2.设计思路 首先是界面的问题,既然课设的题目是简单画图,那在建立工程的时候就要选择文档结构而不是以前做的基于对话框。可选择单文档结构或多文档结构,但想到画图界面一般只有一个,从简洁的角度考虑,选择单文档结构。而且用户界面在设计的时候要尽可能简单美观,一目了然,对相应功能有图标提示,使用户方便使用。 然后便是画图功能的具体实现。分析课设要求,可以发现功能一要求的的椭圆、矩形、直线可以分别通过Ellipse();、Rectangle();、MoveTo();、LineTo();这四个函数来实现。功能二控制画笔线宽和颜色可以给二者分别关联参数,通过改变线宽参数值来控制线宽,通过调用通用对话框改变颜色参数值来控制颜色。功能三对图形进行颜色填充虽以前未接触过,但查阅资料后发现可以调用ExtFloodFill();并合理设定参数值来实现。功能四的实时显示功能可以通过调用MouseMove();函数来实现。 这些功能需要建立菜单资源来表示各个功能选项,并建立相应的消息响应函数来进行实现。另外,画图程序主要是通过鼠标来进行操作,所以要对鼠标消息的响应及处理函数多下功夫来思考和编写。 至于额外添加的功能,工具栏通过添加工具栏资源和关联相应菜单中画图功能ID实现;铅笔、橡皮的功能则是利用MouseMove();函数,在其中做了一些改动来实现。

函数图象的分析与作图(一)(含答案)

学生做题前请先回答以下问题 问题1:确定函数图象,通常研究不同背景下两变量之间的函数关系,以函数图象的形式进行描述.常考查_________________________. 处理思路: ①____________________; ②____________________; ③结合表达式进行验证. 函数图象的分析与作图(一) 一、单选题(共6道,每道16分) 1.如图,在边长为4的正方形ABCD中,动点P从点A出发,以每秒1个单位长度的速度沿线段AB向点B运动,同时动点Q从点B出发,以每秒2个单位长度的速度沿折线BC-CD运动,当点P运动到点B时,P,Q两点同时停止运动.设点P运动的时间为t,△APQ的面积为S(记初始时刻的面积为0),则S关于t的函数图象为( ) A. B. C. D.

答案:D 解题思路: 试题难度:三颗星知识点:确定函数图象 2.如图,已知等边三角形ABC的边长为2,动点P从点A出发,以每秒1个单位长度的速度沿A→B→C→A的方向运动,到达点A时停止.设运动的时间为x秒,,则y关于x的函数图象为( ) A. B.

C. D. 答案:A 解题思路: 试题难度:三颗星知识点:确定函数图象 3.如图,四边形ABCD是边长为1的正方形,四边形EFGH是边长为2的正方形,点D与点F重合,点B,D(F),H在同一条直线上.将正方形ABCD沿FH向右平移,当点B与点H 重合时停止.设点D,F之间的距离为x,正方形ABCD与正方形EFGH重叠部分的面积为y,则能大致反映y与x之间的函数关系的图象是( )

A. B. C. D. 答案:B 解题思路:

C++类中的静态成员变量和静态成员函数的作用

数据成员可以分静态变量、非静态变量两种. 静态成员:静态类中的成员加入static修饰符,即是静态成员.可以直接使用类名+静态成员名访问此静态成员,因为静态成员存在于内存,非静态成员需要实例化才会分配内存,所以静态成员不能访问非静态的成员..因为静态成员存在于内存,所以非静态成员可以直接访问类中静态的成员. 非成静态员:所有没有加Static的成员都是非静态成员,当类被实例化之后,可以通过实例化的类名进行访问..非静态成员的生存期决定于该类的生存期..而静态成员则不存在生存期的概念,因为静态成员始终驻留在内容中.. 一个类中也可以包含静态成员和非静态成员,类中也包括静态构造函数和非静态构造函数.. 分两个方面来总结,第一方面主要是相对于面向过程而言,即在这方面不涉及到类,第二方面相对于面向对象而言,主要说明static在类中的作用。 一、在面向过程设计中的static关键字 1、静态全局变量 定义:在全局变量前,加上关键字static 该变量就被定义成为了一个静态全局变量。 特点: A、该变量在全局数据区分配内存。 B、初始化:如果不显式初始化,那么将被隐式初始化为0(自动变量是随机的,除非显式地初始化)。 C、访变量只在本源文件可见,严格的讲应该为定义之处开始到本文件结束。 例(摘于C++程序设计教程---钱能主编P103)://file1.cpp //Example 1 #include void fn(); static int n; //定义静态全局变量 void main() {

n=20; cout <

MFC——4个基本类中的成员函数介绍.docx

09121852杜军机械设计及理论 1. CMainFrame ActivateFrame使框架对用户可视并可用 CalcWindowRect每当主框架窗I I的客户区尺寸发生变化或控制条的位置发生变 化,需要重新排列客户区时,调用该函数 Create调用以构造和初始化一个与CFrameWnd对象有关的Windows框架窗口DefWindowProc该函数调用缺省的窗口过程来为应用程序没有处理的任何窗口消 息提供缺省的处理 DestroyWindow销毁指定的窗口 DoDataExchange UpdateData会调用这个函数,调用它来初始化对话框的控件或更新数据 GetActiveDocument得到当前文档的指针 GetActiveFrame 返回活动CFrameWnd 对象 GetScrollBarCtrl调用这个成员函数以获取指定的了滚动控件或分隔窗I I的指针LoadFrame调用以从资源信息屮动态构造一个框架窗口 OnAmbientProperty框架调用这个成员函数以从包含OLE控件的窗口获得ambient属性值。重载这个函数以改变OLE控件容器向它的控件返回的缺省ambient属性值。任何没冇被重载函数处理的ambient属性请求将被传递到慕类的实现中OnChildNotify该函数为重载函数,作为部分消息映射被调用,告诉父窗口即将被告知一个窗口刚刚被创建 OnCmdMsg该函数的功能首先按字节对消息进行排序,对于WM_COMMAND 消息,调用OnCommand消息响应函数,对于WM_NOTIFY消息调用OnNotify 消息响应函数。任何被遗漏的消息将是一个窗I I消息。OnWndMsg函数搜索类的消息映像,以找到一个能处理任何窗口消息的处理函数。如果OnWndMsg函数不能找到这样的处理函数的话,则把消息返冋到WindowProc函数,由它将消息发送给DefWindowProc函数 OnCommand该函数查看这是不是一个控件通知,如果它是,OnCommand函数会试图将消息映射到制造通知的控件;如杲他不是一个控件通知,OnCommand 就会调用OnCmdMsg函数 OnCreateClient为框架构造一个用户窗口 OnFinalRelease木函数在对对象的最后一个OLE参考或对象对别人的后一个OLE 参考被释放时,由框架调用 OnNotify框架调用这个函数以通知控件的父窗I」,在控件中发生了一个事件,或者该控件需要某些类型的信息。OnNotify处理控件通知的消息映射OnSetPreviewMode 设置应用的主框架成为或退出预打印模式 PostNcDestroy在窗口被销毁以后,缺省的OnNcDestroy成员函数调用这个函数。派生类可以利用这个函数來执行自定义的清除工作,比如删除指针PreCreateWindow该函数是一个重载函数,在窗I I被创建而,可以在该重载函数屮改变创建参数 PreSubclassWindow这也是一个重载函数,允许首先子分类一个窗口PreTranslateMessage 在消息被分派至U Windows 函数TranslateMessage 和

mfc简单绘图程序

M F C 简 单 的 绘 图 程 序 ——王帅

目录 摘要 (2) 关键字 (2) 1 引言 (2) 设计目的 ............................................................................................................ 错误!未定义书签。 2 功能说明 (2) 2.1菜单栏....................................................................................................... 错误!未定义书签。 2.1.1图形 (3) 2.1.2画笔 (4) 2.1.3画硬币 (4) 2.2工具栏 (5) 2.3状态栏 (5) 3 功能的实现 (5) 3.1 视图设计 (5) 3.2 编辑资源 (6) 3.3 编程思路及各个函数的实现 (7) (1)思路 (7) (2)代码的实现 (7)

1.为基本形状创建一个基类 (8) 2.基本形状类的创建 (8) 2.1矩形类的创建及定义 (8) 2.2圆形类的创建及定义 (10) 2.3正五边形类的创建及定义 (11) 2.4正三角形类的创建及定义 (14) 2.5椭圆类的创建及定义 (16) 2.6正四边形类的创建及的定义 (17) 2.7正六边形类的创建及定义 (18) 2.8直线类的创建及定义 (19) 3.各基本形状类在CMyDraw2_0类中的调用和绘图的实现 (20) 3.1矩形类的调用与与绘图的实现 (20) 3.2圆形类的调用 (24) 3.3正三角形类的调用 (25) 3.4基本类型调用的剩余代码 (26) 4.画笔的使用、颜色及大小的调整 (29) 5.画硬币 (35) 6.工具栏中的自定义控件 (38) 7.状态栏中的显示 (39) 4程序功能的测试 (41) 5最后总结 (42)

实验八 静态数据成员和静态函数成员

实验八静态数据成员和静态函数成员 任务一: 1、了解多文件工程 本次实验需要创建一个工程,此工程由三个文件组成 1)头文件client.h ——类的声明 2)源文件client.cpp——成员函数的定义 3)源文件test.cpp——main()函数的定义 2、了解CLIENT类 本次实验的主角是CLIENT(客户机)类。在实际生活中,计算机网络的应用模式为client/server(客户机/服务器)模式。情况很简单,即多台客户机与一台服务器连接,服务器为客户机提供服务。 3、实验任务 1)阅读程序代码,仔细分析CLIENT类的各数据成员及函数成员,写出分析结果 2)创建多文件工程,编译并运行 3)为main()函数的各条语句增加注释 4)将数据成员ServerName改为非静态,其它类成员的静态属性不变。 修改程序代码,使客户机a连接到另一台服务器M。(b仍与N连接) 任务二: 生成一个储蓄类CK。用静态数据成员表示每个存款人的年利率lixi。类的每个对象包含一个私有数据成员cunkuan,表示当前存款额。提供一个calLiXi()成员函数,计算利息,用cunkuan乘以lixi除以12取得月息,不计复利,并将这个月息加进cunkuan中。提供设置存款额函数set()。提供一个静态成员函数modLiXi(),可以将利率lixi修改为新值。 实例化两个不同的CK对象saver1和saver2,结余分别为2000.0和3000.0。将lixi设置为3%,计算一个月后和3个月后每个存款人的结余并打印新的结果。 首先定义储蓄类CK,它包含一个私有数据成员cunkuan,数据类型为double,一个静态数据成员年利率lixi,数据类型也为double;包含一个成员函数calLiXi()和一个静态成员函数modLiXi(),其中modLiXi()应含有一个表示要更改的年利率的新值的参数。 完善程序: #include class CK{ double cunkuan; public: ? //定义静态数据成员lixi CK(double c){?}//构造函数 void set(double x){?}//设置存款额 ? //定义静态成员函数modLiXi() void calLiXi(int m=1); };

CString类所有成员函数详解

CString类所有成员函数详解 2009-03-27 10:53 CString类所有成员函数详解 VC里CString是我们最常用的类之一,我们觉得对它很熟悉了,可是你知道它的所有用法吗? 还是系统的学习一下吧,认真看完本文就OK了。 下面开始: CString::Compare int Compare( LPCTSTR lpsz ) const; 返回值字符串一样返回0 小于lpsz 返回-1 大于lpsz 返回1 区分大小字符 CString s1( "abc" ); CString s2( "abd" ); ASSERT( https://www.wendangku.net/doc/4f4392798.html,pare( s2 ) == -1 ); ASSERT( https://www.wendangku.net/doc/4f4392798.html,pare( "abe" ) == -1 ); CString::CompareNoCase int CompareNoCase( LPCTSTR lpsz ) const; 返回值字符串一样返回0 小于lpsz 返回-1

大于lpsz 返回1 不区分大小字符 CString::Collate int Collate( LPCTSTR lpsz ) const; 同CString::Compare CString::CollateNoCase int CollateNocase( LPCTSTR lpsz ) const; 同CString::CompareNoCase CString::CString CString( ); CString( const CString& stringSrc ); CString( TCHAR ch, int nRepeat = 1 ); CString( LPCTSTR lpch, int nLength ); CString( const unsigned char* psz ); CString( LPCWSTR lpsz ); CString( LPCSTR lpsz ); 例子最容易说明问题 CString s1; CString s2( "cat" ); CString s3 = s2; CString s4( s2 + " " + s3 ); CString s5( 'x' ); // s5 = "x"

简单的绘图程序实验报告

面向对象程序设计实训(基于MFC程序设计) 题目: 简单的绘图程序 院系专业: 姓名: 学号: 同组其他学生(学号):

简单绘图程序说明 1、功能分析 目前这个软件的主要功能有如下: 1、画直线:通过OnLine()函数实现。 2、画矩形:通过OnRectangle()函数实现。 3、画圆角矩形:通过OnRoundrect()函数实现。 4、画椭圆:通过OnEllipse()函数实现。 5、铅笔工具:可以画任意线条。通过直接在OnMouseMove(UINT nFlags, CPoint point)函数里面添加代码实现。 6、右键弹出菜单:可以在客户中点击鼠标右键,快速选择常用菜单。通过 OnContextMenu函数实现。 7、状态栏显示鼠标移动的坐标:在程序的右下角显示,通过调用setWidnowText 和GetParent()实现。 8、画图颜色选择:可以画任何颜色的线条,通过OnColor()函数实现。 9、线条类型及线宽的设置:可以将画出的线条设置成实线、虚线、点线、点划 线,双点划线,还可以设置线条的粗细,,通过实例这一功能立刻显示所选择线条的粗细及线型。通过新建CLineSettingDlg类,其中OnSelchangeLineStyle()函数实现线型的改变,OnChangeEditLineWidth()函数实现线宽的改变。再在CDrawView类中调用OnLineSetting()函数实现画笔的对话框, CLineSettingDlg类中的OnPaint()函数是实现示例功能的。 10、窗口的重绘时不擦除原来的内容:新建CShape类用来保存线条的颜色,线 宽,填充色等属性,在窗口大小发生变化时有OnDraw(CDC* pDC)函数进行重绘工作,重绘中调用了各个绘图函数的Draw(CDC *pDC)函数。 11、所绘图形的保存于读取,通过Serialize(CArchive &ar)函数进行序列化操作, 将所绘图形的信息通过文件的形式保存起来。

在名字空间中声明类和成员函数

在名字空间中声明类和成员函数 赵湘宁 虽然很多程序员都熟悉名字空间的概念,但他们常常都是被动地使用名字空间。也就是说他们使用的是第三方定义的成员(如标准库的类和函数),而不是在名字空间中声明自己的类和函数。本文拟讨论如何在名字空间中声明自己的类和函数,以及如何在程序中使用它们。 名字空间是一个范畴,它包含类声明,函数声明,常量声明和模板声明等名字空间成员。例如: namespace proj_alpha { //下面是名字空间proj_alpha 的成员 class Spy {/*..*/}; void encrypt (char *msg); const int MAX_SPIES = 8; } 在上面的例子中,类Spy在一个单独的文件中实现。通常,你是在一个专门的头文件中声明一个类并在不同的源文件中独立地定义其成员函数。那么如何将名字空间成员类分离成多个源文件呢? 下面是名为Foo.hpp 的头文件,其中定义了一个名为NS的名字空间,它包含类Foo的声明: //Foo.hpp namespace NS { class Foo { public: void f(); void g(); }; }//close NS 另外,在一个单独的源文件Foo.cpp中,首先包含头文件Foo.hpp以便实现类Foo的成员函数f()和g(): //Foo.cpp #include "Foo.hpp" void NS::Foo::f() { /*..*/ } void NS::Foo::g()

{ /*..*/ } 为了使用名字空间成员,必须使用成员的全路径名,它由名字空间后跟::合成原名组成。因此,类Foo的全路径名是NS::Foo。这样编译器便可以知道NS是一个名字空间名,头文件Foo.hpp必须在引用NS之前被包含。 名字空间是可以扩展的。也就是说可以声明类,而且所声明的类在其它的.cpp文件中是相同的名字空间成员: //Bar.hpp namespace NS //扩展NS { class Bar { public: void a(); void b(); }; } 在Bar.cpp文件中: #include "Bar.hpp" void NS::Bar::a() {/*..*/} void NS::Bar::b() {/*..*/} 可以看出,虽然Foo和Bar这两个类在不同的头文件中声明,但它们都是名字空间NS的成员。并且编译器和链接器将这两个类看成是同一名字空间的成员。那么,如何在应用程序中使用这些类呢? 在文件main.cpp中,必须要包含声明类Foo和Bar的头文件并加上相应的名字空间引用声明-using: #include "Bar.hpp" #include "Foo.hpp" int main() { using NS::Bar; //使用名字空间 using NS::Foo; //同上 Bar b;

mfc简单绘图程序报告

简单绘图程序 1 需求说明 1.1 问题描述 设计一个简单的绘图应用程序,可以绘制图形或自由绘制线段,可以更改颜色、画笔粗细、保存文件。 1.2功能说明 1.图形绘制功能:直线、椭圆、矩形。 在菜单栏中选择需要的图形(也可以通过工具栏中选择)用鼠标便能在视图中绘出相应的图形。 2.可以绘制自由线段 3.对图形的操作:能通过菜单栏弹出对话框选择线宽、自定义颜色,也可以擦除绘制的线段。 4.可以保存绘图文件,保存后打开可以继续绘制。 2.1.3 数据说明 在程序运行以后,当用户单击某个菜单项时,应该把用户的选择保存起来,以便随后的绘图操作使用。在CDzyView类中添加一个私有变量xz;用来保存用户的选择(直线、矩形、椭圆、自由绘图)在绘制时都可有两点来确定其图形。当鼠标左击时得到一个点,当鼠标停止移动时得到另外一个点。为视图类CDzyView分别捕获鼠标左键按下和弹起这两个消息。当鼠标左键按下时,需要将鼠标当前按下点保存至sx、sy,在鼠标移动停止后,将当前坐标保存至ex,ey.

其他主要数据说明: int fd 判断是否为自由绘图模式int w 线宽 int R RGB中的R int G RGB中的G int B RGB中的B CGraph类中 int m_nType:保存后重绘时用户的选择int qdx; 重绘起点x int qdy; 重绘起点y int zdx; 重绘终点x int zdy; 重绘终点y CLine类中 int cx; 重绘线宽 int sx; 重绘起点x int sy; 重绘起点y int zx; 重绘终点x int zy; 重绘终点y int w; 重绘线宽 自定义颜色对话框关联变量: IDC_EDIT_RED int m_Red IDC_EDIT_GREEN int m_Green IDC_EDIT_BLUE int m_Blue IDC_SCROLL_RED CScrollBar m_Sred IDC_SLIDER_GREEN CSliderCtrl m_Sgreen IDC_SPIN_BLUE CSpinButtonCtrl m_Sblue 2 分析、设计与实现 2.1 主要功能设计与实现

静态成员函数一般情况下只能访问静态成员变量

静态成员函数一般情况下只能访问静态成员变量,因为不接受隐含的this指针。另外作为类的静态成员函数,不用声明对象,便可直接调用,例如类A的静态成员函数fun(); A::fun(); 1、主要用于封装全局变量和全局函数。以避免在文件作用域内包含带外部连接的数据。 例如全局变量:int path;int para1; 解决办法:设计一个全局类,并将这些全局名称声明为静态变量,并编写静态函数来调用这些变量。 class Global{ static int s_path; static int s_para; private: Global();//不实现,避免无意中的实例化 public: //manipulators static void setPath(int path){s_path = path;} static void setPara(int para){s_para = para;} //accessors static int getPath(){return s_path;} static int getPara(){return s_para;} } 2、对自由函数的封装 在.h文件的文件作用域内避免使用自由函数(运算符函数除外);在.c文件中避免使用带有外部连接的自由函数,因此可以使用静态成员函数进行处理。 例如:int getPara();int getPath();我们可以通过声明一个结构的静态方法代替: struct SysUtil{ static int getPath(); static int getPara(); }这样,唯一有冲突危险的就是出现类名SysUtil了。

一种使类成员函数成为 Windows 回调函数的方法

问题:一种使类成员函数成为Windows 回调函数的方法( 积分:100, 回复:62, 阅读:3393 ) 分类:Object Pascal ( 版主:menxin, cAkk ) 来自:savetime, 时间:2004-6-20 2:41:00, ID:2672562 [显示:小字体| 大字体] 一种使类成员函数成为Windows 回调函数的方法 https://www.wendangku.net/doc/4f4392798.html, savetime2k@https://www.wendangku.net/doc/4f4392798.html, 2004.6.20 本文排版格式为: 正文由窗口自动换行;所有代码以80 字符为边界;中英文字符以空格符分隔。 未经作者同意请勿在在任何公共媒体转载 大富翁satanmonkey 提出一个问题:HOOK 的时候,那个回调函数怎么弄才能做成类的成员?现在回调函数不能是类成员函数,访问不了类的成员变量。 https://www.wendangku.net/doc/4f4392798.html,/delphibbs/dispq.asp?lid=2624773 后来又在另一篇贴子上也看到类似的问题,看来解决这个问题还有点用(我现在还不知道这有什么用处),所以趁着今天周末思考一下。 (太想睡了,下面只好草率地说明,如有不清楚请提问,或者日后有空再详作解释) 一开始我的想法是在类成员的回调函数内部复制参数的值,差不多理顺了,后来发现如果回调函数有返回值时,这种方法不行... 只好重新开工,用手工编制机器码的方法完成,其中查询JMP $00001111 这样的立即数跳转机器指令花了一个小时,结果是没有找到,只好以JMP [$00001111] 这个代码代替。如果有谁知道前一种跳转指令的机

简单画图程序-课程设计

简单画图程序-课程设计 目录 1. 基本功能描 述 ............................................................. 1 2. 设计思路 ................................................................. 1 3. 软件设 计 (3) 3.1 设计步 骤 (3) 3.2 界面设 计 (6) 3.3 关键功能的实 现 ...................................................... 7 4. 结论与心 得体会 ........................................................... 8 5. 参考文 献 ................................................................. 9 6. 思考 题 (9) 7. 附 录 ..................................................................... 9 7.1 调试报 告 (9)

7.2 测试结 果 (10) 7.3 关键源代 码 (1) 武汉理工大学《专业课程设计2(面向对象程序设计)》课程设计说明书 简单画图程序 1. 基本功能描述 1) 在菜单处的有相应的菜单项,可以选择绘制的图形形状,如直线、矩形及椭圆,可 -5可供选择,还可以选择线色以及填充色,通过弹出的颜色对话框选择以选择线宽,有1 需要的颜色,如果不选择线宽、线色以及填充色,则按默认的画笔以及画刷来绘制选择的图形。 2) 选择好图形后,通过鼠标可以绘制出相应的直线,矩形或椭圆,鼠标的按下确定图形的起点,鼠标的拖动则确定了图形的终点,即通过鼠标的拖动来决定图形的大小,鼠标弹起,此图形则绘制完毕。 3) 增添了工具栏,有相应的选择项,可以更方便地实现相应的功能。 2. 设计思路 1) 对需要用到的变量进行初始化。 2) 选择相应的图形之后就响应相应的消息处理函数,给shape赋对应的值。选择不同的线宽,线色与填充色,则改变画笔和画刷的属性。 3) 鼠标的按下响应LButtonDown(),定义起点的坐标,鼠标的拖动响应MouseMove()改变终点的坐标,鼠标的弹起响应LButtonUp(),刷新,得到绘制图形。

物理实验数据记录、作图规范及excel使用介绍

物理实验数据记录、作图规范及Excel使用方法简单介绍 一、数据记录规范 物理实验要求采用表格记录数据,其中记录数据必须包括“表头”、“物理量”、“单位”、“数据”四部分,缺一不可。 以单摆测量重力加速度为例: 表一:摆长为70cm时不同测量次数n测得的周期T 注意:1、表头,即表格的名字,要放在表格的正上方! 2、数据记录时请仔细检查有效数字位数是否正确! 二、常见作图规范 物理实验很多时候要求依据记录的数据作出相应的图形,在作图时,图中应包括“图的名称”、“纵、横坐标物理量和单位”、“纵、横坐标轴标度值”、“数据点和拟合的趋势线”、“拟合趋势线的方程表达式和R值”和“图例”六部分,缺一不可。 以电阻应变式传感器实验作图为例说明:

Excel (以2010版本为例)在物理实验中的应用: 1、 利用Excel 作图并求出拟合曲线 操作方法: (1)、将所测数据输入到Excel 表格中,最好保证第一列为自变量,即x 轴数据:如图所示: 图的名称 物理量和 单位 图例 拟合曲线表达式及R 2 因子 合适的坐标标度 数据点及拟合的曲线

(2)、选中需要作图的数据,如图所示:选中x和y1列 (3)、在选中数据的基础上,点击菜单栏的“插入”,找到“散点图”,点击如图所示的散点图。 可以得到如下所示的结果:

(4)、选中上一步得到的图形,在菜单栏找到“布局”选项,可以看到在布局选项卡下边有“图表标题”、“坐标轴标题”、“图例”、“数据标签”、“坐标轴”等选项。每一个选项均可以设置相应的内容 其中“图标标题”请选用图标上方,然后单击图上生成的标题,拖到图的下方,同时将

C++静态成员函数小结

C++静态成员函数小结 一静态数据成员 (1) 1.静态数据成员的定义 (1) 2.静态数据成员被类的所有对象所共享(包括该类派生类的对象) (2) 3.静态数据成员可以成为成员函数的可选参数(普通数据成员则不可以) (2) 4.静态数据成员的类型可以是所属类的类型(普通数据成员则不可以) (3) 5.静态数据成员的值在const成员函数中可以被合法的改变 (3) 二静态成员函数 (3) 1.静态成员函数的地址可用普通函数指针储存(普通成员函数地址需要用类成员函数 指针来储存) (4) 2.静态成员函数不可以调用类的非静态成员 (4) 3.静态成员函数不可以同时声明为virtual、const、volatile函数 (4) 类中的静态成员真是个让人爱恨交加的特性。我决定好好总结一下静态类成员的知识点,以便自己在以后面试中,在此类问题上不在被动。 静态类成员包括静态数据成员和静态函数成员两部分。 一静态数据成员 类体中的数据成员的声明前加上static关键字,该数据成员就成为了该类的静态数据成员。和其他数据成员一样,静态数据成员也遵守public/protected/private访问规则。同时,静态数据成员还具有以下特点: 1.静态数据成员的定义 静态数据成员实际上是类域中的全局变量。所以,静态数据成员的定义(初始化)不应该被放在头文件中。其定义方式与全局变量相同。举例如下: xxx.h文件 class base{ private: static const int _i;//声明,标准c++支持有序类型在类体中初始化,但vc6不支持。 }; xxx.cpp文件 const int base::_i=10;//定义(初始化)时不受private和protected访问限制. 注:不要试图在头文件中定义(初始化)静态数据成员。在大多数的情况下,这样做会引起重复定义这样的

几何画板教程第二节:用绘图工具绘制简单的组合图形

第二节用绘图工具绘制简单的组合图形 下面我们用绘图工具来画一些组合图形,希望通过一下范例的学习,你能够熟悉绘图工具的使用,和一些相关技巧。 例1、三角形(一) 一、制作结果如图所示,拖动三角形的顶点,可改变三角形的形状、大小 这个三角形是动态的三角形,它可以被拖成下列三角形之一,如图9所示。 图9 二、要点思路熟悉“直尺工具”的使用,拖动图中的点改变其形状。 三、操作步骤观察图10,你能明白三角形就是用【直尺工具】画三条首尾相接的线段所组成的图形。 图10 1、打开几何画板,建立新绘图 2、单击【直尺工具】,将光标移到在绘图区,单击并按住鼠标拖动,画一条线段,松 开鼠标。 3、在原处单击鼠标并按住拖动,画出另一条线段,松开鼠标。(注意光标移动的方向) 4、在原处单击鼠标并按住拖动,画出第三条线段,光标移到起点处松开鼠标。(注意起点 会变色) 5、将该文件保存为“三角形.gsp” 拓展:你也可以将光标移到在绘图区,单击并松开鼠标拖动,画一条线段,单击鼠标。在原处再单击鼠标并松开拖动,画出另一条线段,单击鼠标。在原处单击鼠标并松开拖动,画出第三条线段,光标移到起点处单击鼠标。 例2三角形(二) 一、制作结果三角形三边所在的线分别是直线、射线和线段,拖动三角形的顶点可以改变三角形的大小和形状,如图11所示。在讲解三角形的外角时,就可构造此图形。 图11

二、知识要点学会使用【线段工具】、【直线工具】、【射线工具】以及它们相互之间的切换。 三、操作步骤 1、打开几何画板,建立新绘图。 2、选择画直线工具将光标移动到【直尺工具】上按住鼠标键不放,移动光标到【直线工 具】上,松开鼠标,如图12所示。 图12 3、画直线将鼠标移动到画板中,按下鼠标键,向右拖曳鼠标后松鼠标键。 4、选择画射线工具用鼠标对准【直线工具】,按下鼠标键并拖曳到【射线工具】处松鼠 标,如图13所示。 图13 5、画射线将鼠标对准定义直线的左边一点(在按下鼠标左键之前请注意窗口左下角的提 示),按下鼠标键,向右上拖曳鼠标后松鼠标键。 6、选择画线段工具用鼠标对准画线工具,按下鼠标键并拖曳到线段工具处松鼠标。如图 14所示。 图14 7、画线段将鼠标对准定义射线的右上一点C(注意窗口左下角的提示信息),按下鼠标 键,向定义直线的右边一点B拖动(注意提示),匹配上这一点后松鼠标。8、将该文件保存为“三线三角形.gsp” 例3、圆内接三角形 一、制作结果如图15所示所示,拖动三角形的任一个顶点,三角形的形状会发生改变,但始终与圆内接。 图15 二、要点思路学会使用画线工具在几何对象上画线段 三、操作步骤如图16所示 图16 1、打开几何画板,建立新绘图。

C++中静态成员函数访问非静态成员变量

C++中静态成员函数访问非静态成员变量 这两天写一个简单的程序,由于程序运行占用cpu比较厉害,导致运行中界面窗口无法交互,因此想到了多线程,以前没有接触过mfc多线程,在网上看了两篇文章,觉得也不过如此,就开始动手写了,结果发现即使是看别人写很简单,自己动手也会出现很多问题,哪怕是看起来真的很简单的问题。 这里遇到的问题就是由于多线程的函数必须是static的,然后需要在里面调用non-static的函数,我就没有办法了,于是又开始网上找资料,下面就将这篇文章转贴过来,供大家学习思考:先看一个class class a { public: static FunctionA() { menber = 1; } private: int menber; } 编译上述代码,出错。原因很简单大家都知道,静态成员函数不能访问非静态成员,这是因为静态函数属于类而不是属于整个对象,静态函数中的 member可能都没有分配内存。静态成员函数没有隐含的this自变量。所以,它就无法访问自己类的非静态成员。(看过一篇很好的文章《浅析C++中的this指针》介绍这个方面的详细内容)那要想访问怎么办呢?地球人都知道只要将: int menber; //change the line above to: static int menber; 但是这个方法让我们不得不将static function内用到的成员变量都变成static的了,而且static 的成员还要显式初始化,有没有更好的方法?答案是肯定的。如下: class a { public: static FunctionA(a* _a) { a-> menber = 1; (window.cproArray = window.cproArray || []).push({ id: "u2280119" }); } private: int menber; } 前提是这个类要分配了内存空间。其实这里我做的就是将一个对象指针作为静态成员函数的“this”指针,意在模仿传递非静态成员函数里this变量。

简单的画图软件画流程图

流程图是一种表示算法的图示,通常用图形将操作步骤,用带箭头的线连接起来的一系列操作,用以表示执行任务的前后步骤。通过流程图直观的展示,更易于工作参与人员的理解。根据美国标准化协会确定的流程图符号,也常被世界工作者所采用,常用的流程图符号有处理框、判断框、输入输出框、起止框、连接点、流程线和注释框。 传统的流程图用连接线指出各项工作顺序,对于新手来说,并不能掌握其中的规律,画出来的流程图,让阅读者花费很大的精力去了解整个流程和算法。如果我们可以借助模板,这样就可以规律性的修改各节点的顺序组成,让阅读者更容易从头到尾的看下去。亿图图示正好满足以上优点,还有额外三大特点:操作简单、模板丰富并且兼容多种文件。 流程图模板 亿图图示可以创建多种类型的流程图:事件流成图、工作流程图和程序流程图等等。

流程图例子 丰富的例子可帮助我们快速绘制想要的流程图框架,方便二次编辑。 选择好专业的流程图工具,接下来我们详细的了解一下绘制步骤。 首先下载并安装亿图图示软件,选择新建流程图,创建空白文档进入画布,当然也可以选择自己喜欢的流程图模板点击进入。 其次,在左侧的符号栏里有各种符号,用来搭建整个框架,选择需要的符号,直接拖拽到画板位置,利用软件的网格和标尺定位好图形符号的位置 最后,记得双击图形,输入补充文本关键词。如果想要流程图显得不那么单调,可以通过上方的样式栏更换主题颜色,使得流程图更专业。

亿图图示,即亿图图示专家(EDraw Max),是一款基于矢量的绘图工具,包含大量的事例库和模板库。可以很方便的绘制各种专业的业务流程图、组织结构图、商业图表、程序流程图、数据流程图、工程管理图、软件设计图、网络拓扑图等等。它帮助您更方便,更快捷的阐述设计思想,创作灵感。

静态函数 静态数据成员与静态成员函数 为什么虚函数必须是非静态成员函数 构造函数能为static吗

静态函数静态数据成员与静态成员函数为什么虚函数必须是非静态成员函数构造函数能为static吗? 2009-07-05 14:27 静态函数 用static声明的函数是静态函数。静态函数可以分为全局静态函数和类的静态成员函数。 Static关键字 在类中,用static声明的成员变量为静态成员变量,它为该类的公用变量,在第一次使用时被初始化,对于该类的所有对象来说,static成员变量只有一份。用static声明的方法是静态方法,在调用该方法时,不会将对象的引用传递给它,所以在static方法中不可访问非static的成员。 静态方法不再是针对于某个对象调用,所以不能访问非静态成员。 可以通过对象引用或类名(不需要实例化)访问静态成员 C++类静态数据成员与类静态成员函数 函数调用的结果不会访问或者修改任何对象(非static)数据成员,这样的成员声明为静态成员函数比较好。且如果static int func(....)不是出现在类中,则它不是一个静态成员函数,只是一个普通的全局函数,只不过由于static的限制,它只能在文件所在的编译单位内使用,不能在其它编译单位内使用。 静态成员函数的声明除了在类体的函数声明前加上关键字static,以及不能声明为const或者volatile之外,与非静态成员函数相同。出现在类体之外的函数定义不能制定关键字static。 静态成员函数没有this指针。 在没有讲述本章内容之前如果我们想要在一个范围内共享某一个数据,那么我们会设立全局对象,但面向对象的程序是由对象构成的,我们如何才能在类范围内共享数据呢? 这个问题便是本章的重点:声明为static的类成员或者成员函数便能在类的范围内共同享,我们把这样的成员称做静态成员和静态成员函数。 下面我们用几个实例来说明这个问题,类的成员需要保护,通常情况下为了不违背类的封装特性,我们是把类成员设置为protected(保护状态)的,但是我们为了简化代码,使要说明的问题更为直观,更容易理解,我们在此处都设置为public。 以下程序我们来做一个模拟访问的例子,在程序中,每建立一个对象我们设置的类静态成员变自动加一,代码如下: #include using namespace std;

相关文档