计算机二级考试C++复习资料类的其他几点问题.docx
- 文档编号:4671061
- 上传时间:2022-12-07
- 格式:DOCX
- 页数:9
- 大小:17.17KB
计算机二级考试C++复习资料类的其他几点问题.docx
《计算机二级考试C++复习资料类的其他几点问题.docx》由会员分享,可在线阅读,更多相关《计算机二级考试C++复习资料类的其他几点问题.docx(9页珍藏版)》请在冰豆网上搜索。
计算机二级考试C++复习资料类的其他几点问题
2019年计算机二级考试C++复习资料:
类的其他几点问题
一、拷贝构造函数
拷贝构造函数在下列情况下被调用:
用已经存有的对象去初始化同一个类的另一个对象;在函数的参数中,以传值方式传递类对象的拷贝;类对象的值被用做函数的返回值。
拷贝构造函数和前面说到的转换构造函数有些相似。
转换构造函数是把一个类的对象转化为另一个类的对象;拷贝构造函数是用一个已经存有的对象的值实例化该类的一个新对象。
不同对象间的初始化和赋值的区别:
赋值操作是在两个已经存有的对象间实行的;而初始化是要创建一个新的对象,并且其初值来源于另一个已存有的对象。
编译器会区别这两种情况,赋值的时候调用重载的赋值运算符,初始化的时候调用拷贝构造函数。
如果类中没有拷贝构造函数,则编译器会提供一个默认的。
这个默认的拷贝构造函数仅仅简单地复制类中的每个成员。
#includeiostream.h
#includestring.h
classDate
{
intmo,da,yr;
char*month;
public:
Date(intm=0,intd=0,inty=0);
Date(constDate&);
~Date();
voiddisplay()const;
};
Date:
:
Date(intm,intd,inty)
{
staticchar*mos[]=
{
January,February,March,April,May,June,
July,August,September,October,November,December
};
mo=m;da=d;yr=y;
if(m!
=0)
{
month=newchar[strlen(mos[m-1])+1];
strcpy(month,mos[m-1]);
}
else
month=0;
}
Date:
:
Date(constDate&dt)
{
mo=dt.mo;
da=dt.da;
yr=dt.yr;
if(dt.month!
=0)
{
month=newchar[strlen(dt.month)+1];
strcpy(month,dt.month);
}
else
month=0;
}
Date:
:
~Date()
{
delete[]month;
}
voidDate:
:
display()const
{
if(month!
=0)
cout< : endl; } intmain() { Datebirthday(6,24,1940); birthday.display(); Datenewday=birthday; newday.display(); Datelastday(birthday); lastday.display(); return0; } 本例中,用到了两次拷贝构造函数。 一个是使用普通的C++初始化变量的语句: Datenewday=birthday; 另一个是使用构造函数的调用约定,即把初始化值作为函数的参数: Datelastday(birthday); 二、类的引用 在函数参数和返回值中,如果一定要使用传值方式,那么使用类对象的引用,是一个提升效率的方法。 类的数据成员也能够是一个引用,但必须注意: 第一,一个引用必须初始化。 通常一个类对象并不会像结构那样用大括号来初始化,而是调用构造函数。 所以在构造函数里必须初始化类当中的引用成员。 第二,引用是一个别名。 即使类里面的引用在使用方式上看起来和类的一般数据成员没有什么区别,但是作用在其上的操作,实际上是对用来初始化它的那么对象实行的。 #includeiostream.h classDate { intda,mo,yr; public: Date(intd,intm,inty) {da=d;mo=m;yr=y;} voidDisplay()const {cout< }; classTime { inthr,min,sec; public: Time(inth,intm,ints) {hr=h;min=m;sec=s;} voidDisplay()const {cout< '< '< }; classDateTime { constDate&dt; constTime&tm; public: DateTime(constDate&d,constTime&t): dt(d),tm(t) { //empty } voidDisplay()const { dt.Display(); cout<<''; tm.Display(); } }; intmain() { Datetoday(7,4,2004); Timenow(15,20,0); DateTimedtm(today,now); dtm.Display(); return0; } 我们来看看这个程序中DateTime的构造函数的格式: 冒号操作符引出了一个参数初始化表。 必须使用这种格式来初始化引用数据成员,而不能够在函数体内来实行初始化工作。 如果构造函数像上例一样不是内联的,那么不要在类声明中构造函数的原型上使用冒号和初始化值表,而是像下面这样,把参数初始化表放在定义构造函数的地方: ClassDateTime { constDate&dt; constTime&tm; public: DateTime(constDate&d,constTime&t); } DateTime: : DateTime(constDate&d,constTime&t): dt(d),tm(t) { //empty } 能够使用构造函数的参数初始化表来初始化任何数据成员。 特别是常量数据成员,和引用一样,只能在参数初始化表里实行初始化,这是因为不能够在构造函数内部为常量数据成员赋值。 当一个类含有引用数据成员时,一旦引用被实例化和初始化以后,就无法修改它的值,所以该类不可能彻底地重载赋值运算符函数。 三、构造函数的参数初始化表 如果类对象的某些数据成员没有载构造函数内部被初始化,那么必须使用构造函数的参数初始化表对他们实行初始化。 否则,编译器不止到该如何初始化这些还等着在构造函数内部赋值的成员。 我们习惯用参数初始化表来初始化所有数据成员。 classDate { intmo,da,yr; public: Date(intm=0,intd=0,inty=0); }; classEmployee { intempno; Datedatehired; public: Employee(inten,Date&dh); }; 能够用下面两种方法编写Employee类的构造函数: Employee: : Employee(inten,Date&dt) { empno=en; datehired=dh; } 或者; Employee: : Employee(inten,Date&dt): empno(en),datehired(dh) { //empty } 虽然这两种方法效果是一样的,但是根据Date对象默认构造函数的复杂性的不同,这两种形式的效率差别是很大的。 四、对const修饰符的简单说明 如果一个对象被声明为常量,那么该对象就不能够调用类当中任何非常量型的成员函数(除了被编译器隐式调用的构造函数和析构函数)。 看下面的代码; #includeiostream.h classDate { intmonth,day,year; public: Date(intm,d,y): month(m),day(d),year(y){} voiddisplay() { cout<} } intmain() { constDatedt(4,7,2004); dt.display();//error return0; } 这个程序即使编译时没有问题,但运行时却出错了。 这是因为常量对象不能调用非常量函数。 编译器只看函数的声明,而不在乎函数的具体实现。 实际上函数的实现能够在程序中的任何地方,也能够是在另一个源代码文件中,这就超过了编译器的当前可见范围。 //date.h classDate { intmonth,day,year; public: Date(intm,d,y); voiddisplay(); }; //date.cpp #includeiostream.h #includedate.h Date: : Date(intm,d,y): month(m),day(d),year(y){} voidDate: : display() { cout<} //program.cpp #includeiostream.h #includedate.cpp intmain() { constDatedt(4,7,2004); dt.display(); return0; } 解决出错的问题有两个方法: 第一是声明display()函数为常量型的 //indate.h voiddisplay()const //intdate.cpp voidDate: : display()const { cout<} 另一个解决方式就是省略掉Date对象声明里的const修饰符。 Datedt(4,7,2004); 还有另一个容易出错的地方: voidabc(constDate&dt) { dt.display();//error提示display没有const修饰符 } 函数abc()声明了一个Date对象的常量引用,这说明该函数不会修改传递进来的参数的值。 如果Date: : display()函数不是常量型的,那么在函数abc()里就不能调用它,因为编译器会认为Date: : display()函数有可能会修改常量的值。 不论类对象是否是常量型的,它必须修改某个数据成员的值时,ANSI委员会设立了mutable关键字。 五、可变的数据成员 假设需要统计某个对象出现的次数,不管它是否是常量。 那么类当中就应该有一个用来计数的整型数据成员。 只要用mutable修饰符来声明该数据成员,一个常量型的成员函数就能够修改它的值。 #includeiostream.h classAValue { intval; mutableintrptct; public: AValue(intv): val(v),rptct(0){} ~AValue() { cout<} voidreport()const; }; voidAValue: : report()const { rptct++; cout< } intmain() { constAValueaval(123); aval.report(); aval.report(); aval.report(); return0; }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 计算机 二级 考试 C+ 复习资料 其他 问题