北方工业大学面向对象真题.docx
- 文档编号:5401477
- 上传时间:2023-05-08
- 格式:DOCX
- 页数:16
- 大小:19.72KB
北方工业大学面向对象真题.docx
《北方工业大学面向对象真题.docx》由会员分享,可在线阅读,更多相关《北方工业大学面向对象真题.docx(16页珍藏版)》请在冰点文库上搜索。
北方工业大学面向对象真题
一、判断题(10分)
1.缺省构造函数是参数表中没有参数的构造函数(错)
2.类的静态数据成员必须该类声明之外被初始化(对)
3.声明一个引用变量同时要对它初始化(对)
4.constint*p;这个语句的意思是指针P不能修改(错)
5.下面定义的类的成员函数重载形式是否正确(错)
Voidfunc(intx);
Voidfunc(intx,floaty=1.0);
6.一个类的友元函数可以访问类的私有成员(对)
7.C++提供的重载运算符的方法使得程序员可以重写所有运算符功能(错)
8.一个基类指针可以指向其派生类的对象,同样一个派生类指针也可以指向其基类的对象(错)
9.对于一个对象来说,析构函数是最后一个被调用的成员函数(对)
10.一个作为基类的类里如果定义了虚函数,我们称这个类为抽象基类(错)
1、(√)
原因:
这是抽象类的定义,如:
classA
{
virtualvoidprint()const=0;//纯虚数,函数体的具体实现要在类外;
};则A为抽象类。
2、(×)
原因:
使用声明是向局部作用域里添加东西,而使用指示只是使一些名字能够被访问,而不增加任何东西。
这也维持了一种非常重要的性质:
局部声明的名字隐藏名字相同的非局部声明。
3、(×)
原因:
通过继承,在派生类中会有一份基类成员的拷贝,所以基类指针可以指向派生类对象,然而此时,这个指针只能调用基类的被继承过来的成员,虽然它指向了派生类对象,但是派生类自己定的成员,该指针是访问不到的。
反之,派生类指针是不能指向基类的。
(就好像是父亲的权力比孩子的权利大,父亲可以指孩子,孩子却不能指父亲^^)
4、(√)
原因:
公有继承后,派生类已具有基类的特征,基类所具有的功能,这时候已经遗传给了派生类,所以基类能完成的事情,派生类就也能完成了。
5、(√)
原因:
const紧挨着*,说明它修饰的是指针,指明该指针是一个常指针(不能改变的),这个指针指向的类型是int;而constint*p;这种情况,const紧挨着int,说明它修饰的是所指向的整型量,而不是指针,也即该指针指向的是一个常整型(指向的这个量不能改变),指针是可以变的,可以指向其他的整型量。
6、(√)
原因:
友元函数不是类的成员函数,但是可以访问类的私有和保护成员。
当然就可以访问公有成员了。
友元函数就是破坏类的封装机制,让类中不可见的东西可见。
7、(×)
原因:
voidfunc(intx);voidfunc(intx,floaty=1.0);当出现funx
(2)的时候,它就迷惑了,不知道调哪个好,尽管func(intx,floaty=1.0)比前一个函数多了一个参数floaty,但是y有一个默认值,即不写这个参数,会默认你传给y的值是1.0
(对于voidfunc(intx,floaty=1.0)函数来说,func
(2)和func(2,1.0)的效果是一样的)。
8、(×)
原因:
=()[]->必须重载为成员函数
9、(√)
原因:
析构函数是在对象的生存期即将结束的时刻由系统自动调用的,这调用完之后,对象就消失了,相应的内存空间也被释放。
10、(×)
原因:
初始化的顺序是以类里成员数据的定义为准,而不是按初始化列表的定义顺序执行。
这是为保证成员数据释放时的顺序和初始化顺序正好相反。
二:
叙述面向对象技术的特点(10分)
答案:
1模块性2封装性3代码共享4灵活性5易维护性6增量性设计7局部存储与分布式处理
三:
名次解释(15分)
1.对象
对象是一个实体,是一个名字标识、自身状态和自身功能。
定义:
OBJ
2.封装和协议
封装是面向对象技术基本原理的基础,对象是类的实例,对象的所有数据和对这些数据的操作封装在一起,外部对象只有通过给它发消息来改变或者得到这些数。
而协议由一个对象能够接受并且愿意接受的所有消息构成的对外接口。
其他对象只能向该对象发协议中所提供的消息。
3.类和实例
类:
对一组相似对象的共同抽象描述,它将该对象所具有的共同特征包括操作特征和存储特征结合在一起,用于说明该组对象的能力和性质。
实例:
任何单个对象都是某个类的实例,一个类的所有实例都采用同样的处理方法处理消息,但每个实例又有自己的私有存储单元。
类和实例的关系是抽象与具体的关系。
四:
改错
1、classCX
{
intm_nx;
public:
operatorint{returnm_nx;}
此处错误:
应改为operatorint(),因为重载int是函数,它掉了(),,有了这个函数,再出现CXa,int(a),就可以把对象a转化为整型了,如果没有operatorint()这个函数,直接写int(a),就会提示不能把类类型转化为整型,其实这个函数就是重载强制类型转换,把以前不能进行的强制转换让他可以转换。
下面的operatorCX()也是这个作用:
把其他类型转化为类类型。
↓
};
classCY:
publicCX
{
CXm_cx;
intm_mv;
public:
CY(intv){m_mv=v;}
operatorCX(){returnm_cx;}
};
voidf(int);
voidg()
{
CYy(50);
f(y);此处错误:
因为声明时voidf(int)参数是一个整型,而y是一个对象,是类类型,两者不区配。
}
2、classCbase{
public:
charm_cvalue;
intgetValue();
chargetValue();此处错误,因为不能仅根据返回值的不同来区分两个函数,即编译器认为chargetValue();intgetValue();这是同一个函数。
virtualvoidf();
virtualvoidf2();
staticvoidstaticfun();
intgetInt()const;
};
classCDerived1:
publicCBase
{
public:
voidset();
intf1();
voidf2();
};
classCDerived2:
publicCBase
{
};
staticvoidCBase:
:
staticfun(){}此处错误,类的静态成员在类外进行初始化或实现的时候,要去掉关键字static
intCBase:
:
getInt()此处错误,类中的函数是intgetInt()const;,这个intCBase:
:
getInt()没有const,它们不是同一个函数,它会重载类中的intgetInt()const,加上const就没问题了。
{
return1;
}
voidfunc()
{
CDerived1d1;
CDerived2d2;
d1.set
(1);此处错误,d1.set()默认调用的是CDerived1类中自身的voidset(),这个函数是没有参数的,不会自动调用从CBase中继承来的voidset(int)函数。
如果加上类名作用域分辨符就没问题了,如下面。
↓
d1.CBase:
:
set
(1);
charc1=d1.m_cvalue;
charc2=d2.m_cvalue;
}
3、template
template
template
每个模板参数必须由关键字(class/typename)修饰
四.用C++按面向对象的继承风格设计一组画图类(10分)
classCShape{
public:
CShape{}
virtual~CShape(){}
virtualvoidDraw()=0
};
classCRectangle:
:
publicCShape(){
public:
CRectangle(){}
};
voidCRectangle:
:
Draw(){
//画矩形的代码
}
classCEllipse:
publicCShape{
public:
CEllipse(){}
};
voidCEllipse:
:
Draw(){
//画椭圆的代码
}
classCCircle:
publicCShape{
public:
Circle(){}
};
voidCCircle:
:
Draw(){
//画圆的代码
}
五.用c++按面向对象的风格设计一个复数(complex)类,并且实现拷贝构造函数并重载=,+,-,*运算符(15分)
ClassCComplex{
public:
ccomplex(doubledblreal=0.0,doubledblimaginary=0.0&);//构造函数
ccomplex(constccomplex&);//拷贝构造函数
ccomplex&opertaor=(constccomler&);
//返回值类型operator运算符号(参数说明)
friendccomplexoperator+(constccomplex&,constccomplex&);
friendccomplexoperator-(constccomplex&,constccomplex&);
friendccomplexoperator*(constccomples&,constccomplex&);
private:
doublem_dblreal;
doublem_dblimaginary;
};
ccomplex:
:
ccomplex(doubledblreal,doubledbimaginary)//构造函数
{m_dblreal=dblreal;
m_dblimaginary=dblimaginay;
}
ccomplex:
:
ccomplex(constccomplex&rs)
{*this=rs;
}
ccomples&ccomplex:
operator=(constccomplex&rs)
{if(this==&rs)
return*this;
else
m_dblreal=rs.m_dblreal;
m_dbimaginary=rs.m_dbimaginary;
return*this;
}
ccomplexoperator+(constccomplex&ls.constccomplex&rs)
{returnccomplex(ls.m_dblreal+rs.m_dblreal,
ls.m_dbimaginary+rs.m_dblimaginary);
}
ccomplexoperator-(constccomplex&ls.constccomplex&rs)
{returnccomplex(ls.m_dblreal-rs.m_dblreal,
ls.m_dbimaginary-rs.m_dblimaginary);
}
ccomplexopertaor*(constccomplex&ls.constccomplex&rs)
{returnccomplex(ls.m_dblreal*rs.m_dblreal-
ls.m_dblimaginary*rs.m_dblimaginary,
ls.m_dblreal*rs.m_dblimaginary+ls.m_dblimaginary*rs.m_dblreal);
}
六、
例子:
classBase
{
public:
virtualvoidprint()
{
cout<<"基类打印函数被调用~!
~"< } }; classDerived: publicBase { virtualvoidprint() { cout<<"派生类打印函数被调用~! ~"< } }; voidmain() { Base*p=newDerived; p->print(); } /*说明: 程序输出: “派生类打印函数被调用~! ~”;明明是基类指针所指向的print(),按理说应该调用基类print()输出: “基类打印函数被调用~! ~”,然而并非如此,就是因为print()函数为虚函数,本例中基类指针指向的是派生类对象,当运行的时候,会自动绑定派生类的print()函数,如果print()函数不是虚函数,则不会有这种动态绑定。 */ 七、 #include"iostream" usingnamespacestd; classFraction { public: Fraction(intx,inty){fenzi=x;fenmu=y;}//构造函数 Fraction(constFraction&frac);//拷贝构造函数; Fraction&operator=(Fractionp);//重载=运算符 constFractionoperator*(constFractiona);//重载乘号运算符 constFractionoperator/(constFractionb);//重载除法运算符 voidoperator++();//重载前置++运算符 voidoperator++(int);//重载后置++运算符 voidDisplay(){cout< private: intfenmu;//分母 intfenzi;//分子 }; Fraction: : Fraction(constFraction&frac)//实现拷贝构造函数 { fenmu=frac.fenmu; fenzi=frac.fenzi; } Fraction&Fraction: : operator=(Fractionp)//实现赋值 { fenmu=p.fenmu; fenzi=p.fenzi; return*this; } constFractionFraction: : operator*(constFractiona)//实现分数相乘; { returnFraction(fenzi*a.fenzi,fenmu*a.fenmu);//分别把分母相乘,分子相乘; } constFractionFraction: : operator/(constFractionb)//实现分数相除; { returnFraction(fenzi*b.fenmu,fenmu*b.fenzi);//第一个分数的分子乘第二个数的分母,第一个数的分母乘第二个数分子; } voidFraction: : operator++()//实现前置++; { fenzi+=fenmu; cout<<"++Fraction: "; } voidFraction: : operator++(int)//实现后置++ { fenzi+=fenmu; cout<<"Fraction++: "; } voidmain() { Fractiona(1,2),b(2,3); a.Display(); cout<<"*"; b.Display(); cout<<"=";//为了显示1/2*2/3= Fractionc=b;//会调用拷贝构造函数; c=a*b;//自动把*右边的操作数b作为参数传递给operator*(constFractiona)函数,执行完后把a*b结果作为参数传递给operator=(Fractionp),实现赋值给c; c.Display();//显示相乘后的结果; cout< a.Display(); cout<<"/"; b.Display(); cout<<"=";//为了显示1/2/2/3= c=a/b;//自动把*右边的操作数b作为参数传递给operator/(constFractionb)函数,执行完后把a/b结果作为参数传递给operator=(Fractionp),实现赋值给c; c.Display();//显示除的结果; cout< a++;//调用operator++(int)后置++ a.Display();//显示后置++的结果 cout< ++b;//调用operator++();实现前置++; b.Display();//显示前置++的结果; } #include"iostream" usingnamespacestd; classComplex { public: Complex(intx=0,inty=0) {shibu=x;xubu=y;} Complex(constComplex&com); Complex&operator=(Complexp); Complexoperator+(constComplexa); Complexoperator-(constComplexb); Complexoperator*(constComplexc); voidDisplay(){cout< private: intshibu; intxubu; }; Complex: : Complex(constComplex&com) { shibu=com.shibu; xubu=com.xubu; } Complex&Complex: : operator=(Complexp) { shibu=p.shibu; xubu=p.xubu; return*this; } ComplexComplex: : operator+(constComplexa) { returnComplex(shibu+a.shibu,xubu+a.xubu); } ComplexComplex: : operator-(constComplexb) { returnComplex(shibu-b.shibu,xubu-b.xubu); } ComplexComplex: : operator*(constComplexc) { returnComplex((shibu*c.shibu)-(xubu*c.xubu), (shibu*c.xubu)+(xubu*c.shibu)); } voidmain() { Complexcom1(5,2),com2(3,4); com1.Display(); cout<<"*"; com2.Display(); Complexcom3=com1; com3=com1*com2; cout<<"="; com3.Display(); cout< com1.Display(); cout<<"+"; com2.Display(); com3=com1+com2; cout<<"="; com3.Display(); cout< com1.Display(); cout<<"-"; com2.Display(); com3=com1-com2; cout<<"="; com3.Display(); cout< }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 北方工业 大学 面向 对象