C++实习报告.docx
《C++实习报告.docx》由会员分享,可在线阅读,更多相关《C++实习报告.docx(15页珍藏版)》请在冰豆网上搜索。
C++实习报告
C++实习报告
实习地点:
信息楼一楼
实习时间:
2012年11月30日
实习内容:
一,构造一个学生类CStudent,要求如下:
①,具有两个保护的成员:
姓名和学号;
②,实现带参数的构造函数,在构造函数中输出“带参构造函数被调用”;
③,实现拷贝构造函数,在其中输出“拷贝构造函数被调用”;
④,实现析构函数,在析构中输出“析构函数被调用”;
⑤,在类的外部,声明一个全局函数voidPrintInfo(CStudentstu);实现对学生信息的输出;
⑥,在main中声明CStudent的对象,并利用PrintInfo实现对它的调用。
程序代码如下:
#include"stdafx.h"
#include"iostream.h"
classCStudent
{
public:
CStudent(char*name1,char*id1);
CStudent(constCStudent&stu);
~CStudent();
voidprint();
protected:
char*name;
char*id;
};
CStudent:
:
CStudent(char*name1,char*id1)
{
name=name1;
id=id1;
cout<<"带参构造函数被调用"<}
CStudent:
:
CStudent(constCStudent&stu)
{
name=stu.name;
id=stu.id;
cout<<"拷贝构造函数被调用"<}
CStudent:
:
~CStudent()
{
cout<<"析构函数被调用"<}
voidCStudent:
:
print()
{
cout<<"姓名:
"<"<}
voidPrintInfo(CStudentstu)
{
stu.print();
}
intmain()
{
CStudentstu1("付杰","20101003794");
CStudentstu2(stu1);
PrintInfo(stu1);
return0;
}
运行结果如下所示:
代码与运行结果分析:
1,最开始关于用voidPrintInfo(CStudentstu)函数实现对学生信息的输出,我的代码是这样的:
voidPrintInfo(CStudentstu)
{
cout<<"姓名:
"<"<}
结果出来了两个错误,说在不能引用受保护成员name和id,看了书本之后我明白了这个错误的原因,于是我在类里面添加了一个共有成员函数voidprint(),这样就可以实现对学生信息的输出了。
2,最开始我主函数里面的代码是这样的:
intmain()
{
CStudentstu1("付杰","20101003794");
PrintInfo(stu1);
return0;
}
运行结果如下所示:
起初我觉得没有调用拷贝构造函数,因为还没有用对象stu1去初始化对象stu2,可运行结果却显示调用了拷贝构造函数,在看了书本和老师的PPT之后,我才明白:
若函数的形参为类对象,调用函数时,实参赋值给形参,系统自动调用拷贝构造函数,voidPrintInfo(CStudentstu)。
还有一种情况,当函数的返回值是类对象时,系统自动调用拷贝构造函数。
小结:
通过这个题目,我掌握了以下内容:
类和对象的定义,如何定义一个类和创建该类的一个对象;类的成员以及类成员的访问控制,类的构造函数,析构函数和拷贝构造函数。
二,声明基类CVehicle,要求如下:
1具有一个虚函数voidRun();输出其运行的方式"在天上或地上跑";
2具有一个函数voidPassenger();输出乘客的类型“人、货物、或者动物”;
3从CVehicle派生一个CCar类,重载以上两个函数,在其中输出其运行的方
式“在地上跑”,以及乘客的类型“人或货物”;
4从CCar派生一个CBuss类,重载以上两个函数,在其中输出其运行的方式“在城市里跑”,以及乘客的类型“上下班的人”;
5声明一个函数voidPrintInfo(CVehicle*ptr)在函数中设用上述两个函数;
6在main函数中声明三种类的对象,再声明基类CVehicle的指针,分别指向这三个变量,然后再分别调用函数PrintInfo,再查看输出的结果,体会静态编译与动态编译的差别。
程序代码如下:
#include"stdafx.h"
#include"iostream.h"
classCVehicle
{
public:
virtualvoidRun()
{
cout<<"在天上或地上跑"<}
voidPassenger()
{
cout<<"人、货物、或者动物"<}
};
classCCar:
publicCVehicle
{
public:
virtualvoidRun()
{
cout<<"在地上跑"<}
voidPassenger()
{
cout<<"人或货物"<}
};
classCBus:
publicCVehicle
{
public:
virtualvoidRun()
{
cout<<"在城市里跑"<}
voidPassenger()
{
cout<<"上下班的人"<}
};
voidPrintInfo(CVehicle*ptr)
{
ptr->Run();
ptr->Passenger();
}
intmain()
{
CVehiclevehicle;
CCarcar;
CBusbus;
CVehicle*ptr;
ptr=&vehicle;
PrintInfo(ptr);
ptr=&car;
PrintInfo(ptr);
ptr=&bus;
PrintInfo(ptr);
return0;
}
运行结果如下:
代码与运行结果分析:
1,为什么最后输出的乘客的类型都是人、货物、或者动物呢,从这个例子可以看到,根据赋值兼容规则,我们可以在基类出现的场合使用派生类进行替代,但是替代之后派生类仅仅发挥出基类的作用;那运行的方式为什么是图中的结果呢,这是因为多态的设计方法可以保证在赋值兼容的前提下,基类、派生类分别以不同的方式来响应相同的消息。
2,为了更好地理解虚函数的作用,我将基类里的voidPassenger()改成了虚函数virtualvoidPassenger(),运行结果如下:
可以看出,虚函数具有继承性,由于基类中声明了虚函数,故在派生类中无论是否说明,同原型函数都自动为虚函数。
小结:
通过这个题目,我掌握了类的继承与派生以及面向对象的多态性,更好地理解了书本上第八章的内容。
三,声明一个点类CRange,要求如下:
1具有两个保护类型的数据成员:
width和height;
2实现带参数的构造函数、拷贝构造函数;
3重载CRange的“+”、“-”、“=”运算符;
4在main函数中对两个CRange对象进行相加,相减,并输出结果。
程序代码如下:
#include"stdafx.h"
#include"iostream.h"
classCRange
{
public:
CRange(floatwidth1,floatheight1)
{
width=width1;
height=height1;
}
CRange(constCRange&obj)
{
width=obj.width;
height=obj.height;
}
CRangeoperator+(CRangeobj1)
{
returnCRange(obj1.width+width,obj1.height+height);
}
CRangeoperator-(CRangeobj2)
{
returnCRange(width-obj2.width,height-obj2.height);
}
CRangeoperator=(CRangeobj3)
{
height=obj3.height;
width=obj3.width;
returnCRange(width,height);
}
voidPrint()
{
cout<<"("<}
protected:
floatwidth,height;
};
intmain()
{
CRangeobj1(30,25),obj2(15,12),obj3(0,0),obj4(0,0);
obj3.operator=(obj1.operator+(obj2));
obj4.operator=(obj1.operator-(obj2));
cout<<"obj1=";obj1.Print();
cout<<"obj2=";obj2.Print();
cout<<"obj3=obj1+obj2=";obj3.Print();
cout<<"obj4=obj1-obj2=";obj4.Print();
return0;
}
运行结果如下:
分析:
obj3=(obj1+obj2);obj4=(obj1-obj2)可以代替主函数中相应的部分,运算符作为成员函数重载时运算符左侧的对象是调用对象,右侧的是作为参数被传递的对象。
小结:
通过这个题目,我掌握了运算符重载的基本方法,只有通过不断地改动程序,看运行结果,才能更好地理解理论知识。
总结:
刚开始学这几章的时候感觉很吃力,有些地方没有得到深层次的理解,但在上机实习之后,我上课时不懂的问题大部分都得到了解决,通过这次实习,我熟练地掌握了封装、继承与多态的相关内容,收获感觉挺大的。
实习地点:
信息楼二楼
实习时间:
2012年12月16日
实习内容:
MFC实习,做一个综合实例,里面包含菜单、工具栏、对话框、GDI。
实习结果及代码分析:
1,在视图类CMfctestView中添加消息响应函数,代码如下:
#include"RoundRectDlg.h"
voidCMfctestView:
:
OnNEWRoundRect()
{
//TODO:
Addyourcommandhandlercodehere
CRoundRectDlgobj;
inta=obj.DoModal();
if(a==IDOK)
{
CDC*pDC=GetDC();
CBrushbsh(RGB(122,212,246));
pDC->SelectObject(&bsh);
pDC->RoundRect(obj.m_x1,obj.m_y1,obj.m_x2,obj.m_y2,obj.m_x3,obj.m_y3);
}
}
这是用来画一个圆角矩形的,利用了RoundRect(intx1,inty1,intx2,inty2,intx3,inty3)函数,其中参数(x1,y1)为指定矩形的左上角位置x与y坐标;(x2,y2)为指定矩形右下角位置x与y坐标,(x3,y3)用于定义矩形四个角上的边角内切椭圆的宽度和高度,值越大,圆角矩形的角就越明显。
如果x3=x2-x1,并且y3=y2-y1,则所绘制的圆角矩形变为一个椭圆。
运行程序,点击菜单中的画图选项,会弹出一个对话框,如下所示:
为什么x1,y1,x2,y2,x3,y3的初始值会如上图所示的那样呢,这是因为我在相应的函数里作了变量的初始化,部分函数代码如下:
CRoundRectDlg:
:
CRoundRectDlg(CWnd*pParent/*=NULL*/)
:
CDialog(CRoundRectDlg:
:
IDD,pParent)
{
//{{AFX_DATA_INIT(CRoundRectDlg)
m_x1=10;
m_x2=300;
m_x3=70;
m_y1=10;
m_y2=200;
m_y3=80;
//}}AFX_DATA_INIT
}
2,在voidCRoundRectDlg:
:
OnOK()函数里添加了UpdateData(TRUE);这是用来实现数据交互的。
然后点击确定按钮,会出现如下图所示的结果:
如果改变变量的值,使得x3=x2-x1,并且y3=y2-y1,绘制的圆角矩形将会变成椭圆,如下图所示:
原先的圆角矩形变成了椭圆
这里因为在对话框中已经实现了数据交互,那工具栏就没有搞得很复杂,就输出一行字,添加的相应的代码如下:
voidCMainFrame:
:
OnNewFunction()
{
//TODO:
Addyourcommandhandlercodehere
MessageBox("工具栏");
}
点击工具栏中的黑正方形图标,出现的结果如下所示:
MFC实习总结:
在老师给的那个综合实例的指导下,再加上自己查了一些资料,初步完成了预设的要求,通过这个实习,我对MFC有了一个简单的了解,熟悉了菜单,对话框,工具栏等资源的使用方法,虽然在实习过程中遇到了一些问题,但在问了学姐和老师之后,大部分问题都得到了解决。