为此,C++提供了一个更好的方法,就是利用类的构造函数来初始化类的数据成员。构造函数具有如下几个特点:构造函数名与类名相同,且没有返回值,不能指定函数类型。构造函数通常被声明为公有属性,但它不能像其他成员函数那样被显式地调用,它是在创建对象时被系统自动调用的。例如,可以将例2.1的MyClass类扩展为MyClass2,使其包含两个构造函数:上述类中包含两个构造函数:一个没有参数,另一个有两个参数。......
2023-11-07
当定义类对象时,构造函数会自动执行。因为一个类可能会有包括默认构造函数在内的不止一种构造函数,下面讨论如何调用特定的构造函数。
1.调用默认构造函数
如果类的定义中没有给出构造函数,则C++语言编译器自动给出一个默认的构造函数,而且默认的构造函数只能有一个,形式如下:
类名∷默认构造函数名()
{
}
若没有定义任何形式的构造函数,系统会自动生成默认的构造函数。若已经定义了构造函数,则系统不会自动生成默认的构造函数,一旦需要,则要求显式地定义这种形式的构造函数。
假设一个类包含有默认构造函数,调用默认构造函数的语法如下:
类名类对象名;
例如,语句:
MyClass2 sa;
将sa定义为MyClass2类型的对象。在这种情况下,会执行默认的构造函数,从而将sa的数据成员初始化为0。因此,在程序中定义一个对象而没有指明初始化时,编译器便按默认构造函数来初始化该对象。
注意:如果定义了一个对象并且希望默认构造函数被执行,在定义语句中,“类对象名”后面是不需要空括号的。如果包含了空括号,编译器将会产生一个语法错误信息。例如,以下语句是非法的:
MyClass2 mysa();
2.调用带参数的构造函数
假设一个类中包含有带参数的构造函数,调用这种带参数的构造函数的语法如下:类名类对象名(参数表)
其中,“参数表”中的参数可以是变量,也可以是表达式。
注意:参数的个数、类型和顺序应该与所定义的构造函数相匹配。如果参数的类型和顺序不与任何构造函数相匹配,则C++将使用类型转换并寻找最佳匹配。例如,一个整型数可能会转换成小数部分为0的浮点数。任何不确定因素都会导致编译错误。
例如,语句:
MyClass2 sa1(120,210);
该语句定义了一个MyClass2类型的对象sa1。这里传递两个int型的值,并与MyClass2类的一个带参数的构造函数相匹配。因此,会执行MyClass2类中带参数的构造函数,从而将数据成员x和y分别赋值为120和210。
3.调用内置数据类型的构造函数
实际上,C++中内置的数据类型都可以看成是类,定义变量时除了可以使用“=”运算符赋初值外,还可以像定义类对象一样调用其构造函数给变量赋初值,例如,以下语句都是正确的:
4.用new动态创建对象
可以用new运算符来动态地建立对象。用new运算符建立对象时,同样也要自动调用构造函数,以便完成对象数据成员的初始化。(www.chuimin.cn)
【例2.5】分析以下程序的执行结果。
解:上述程序中,先声明了一个类Point1,在该类中有一个构造函数。程序的执行结果如下:
First point=>(12,6)
Second point=>(5,12)
从执行结果看到,当执行语句
Point1 a(12,6),*p=new Point1(5,12);
时,不仅定义了Point1类的对象a和一个匿名对象指针p,还自动调用类的构造函数。也就是说,在定义类的对象时就自动调用构造函数进行对象的初始化。这是因为,编译器已悄悄地在a的定义点处插入了一个Point1∷Point1(12,6)的调用。
注意:在创建匿名对象时要调用类的构造函数。
【例2.6】分析以下程序的执行结果。
解:上述程序中,通过对象指针来调用对象的成员函数。对象指针p指向对象s,p->disp()等价于s.disp()。程序执行结果如下:
x=12,y=3
注意:与定义一般对象不同的是,在定义对象指针而不使用new创建新的匿名对象或者定义对象指针指向一个已创建的对象时,都不会调用类的构造函数。
5.用构造函数初始化对象的过程
用构造函数初始化对象的过程,实际上就是对构造函数的调用过程。一般情况下按如下步骤进行。
(1)程序执行到定义对象语句时,系统为对象分配内存空间;
(2)系统自动调用构造函数,将实参传送给形参,执行构造函数体时,将形参值赋给对象的数据成员。完成数据成员的初始化工作。
【例2.7】分析以下程序的执行结果。
解:本程序执行结果如下:
调用带参构造函数
矩形s1的面积=153
调用无参构造函数
矩形s2的面积=0
由程序执行的结果可以看到,在执行Rectangle s1(1,3,8,12)语句定义对象s1时,系统先为对象s1分配内存空间,然后自动调用带参构造函数s1.Rectangle(1,3,8,12),将实参传给形参,在构造函数体内用赋值语句完成对象s1的初始化工作,再调用成员函数s1.Area()求对象s1面积;在执行Rectangle s2语句产生对象s2时,系统自动调用无参构造函数s2.Rectangle(),将私有数据成员初始化为0,再调用成员函数s2.Area()求对象s2面积。
有关C++程序设计基础教程的文章
为此,C++提供了一个更好的方法,就是利用类的构造函数来初始化类的数据成员。构造函数具有如下几个特点:构造函数名与类名相同,且没有返回值,不能指定函数类型。构造函数通常被声明为公有属性,但它不能像其他成员函数那样被显式地调用,它是在创建对象时被系统自动调用的。例如,可以将例2.1的MyClass类扩展为MyClass2,使其包含两个构造函数:上述类中包含两个构造函数:一个没有参数,另一个有两个参数。......
2023-11-07
析构函数被系统自动调用分两种情况。分析以下程序的执行结果。解:本程序执行结果如下:调用带参构造函数矩形s1的面积=153调用无参构造函数矩形s2的面积=0调用了析构函数!......
2023-11-07
程序的执行结果如下:Point复制构造函数被调用Point复制构造函数被调用Point复制构造函数被调用Point复制构造函数被调用Distance构造函数被调用(1,2)和(8,6)两个点的距离:8.06226......
2023-11-07
所以,在定义派生类的构造函数时除了对自己的数据成员进行初始化外,还必须负责调用基类构造函数使基类的数据成员得以初始化。如果派生类中还有子对象,还应包含对子对象初始化的构造函数。最后执行派生类的构造函数。其中,如果派生类新增成员中有某个类的子对象,第步的调用才会执行,否则就直接跳转到第步,执行派生类的构造函数。在某些情况下,派生类构造函数的函数体可能为空,仅起到参数传递作用。......
2023-11-07
运算符重载函数的调用格式与普通成员函数的调用格式类似,以双目运算符重载成员函数为例,其调用格式如下:左运算对象双目运算符右运算对象例如:对于前面的Complex,设计如下主函数:其中,“s3=s1+s2;”和“s4=s1-s2;”两个语句就是调用运算符重载函数。该函数执行完毕,释放tmp对象。......
2023-11-07
程序设计是指设计、编写和调试程序的方法与过程。由于程序是软件的本体,因此软件的质量主要通过程序的质量体现,因此,研究一种切实可行的程序设计方法至关重要。继承是面向对象程序设计方法的一个重要标志,利用继承机制可以大大提高程序的可重用性和可扩充性。......
2023-11-07
当一个实际的函数调用,它既可以和一个重载函数相匹配或是参数转换后与某一重载函数相匹配,又可以与某一模板函数相匹配,这并不会产生二义性。只是调用哪一个需按照一定的规则安排先后次序。在失败后,寻找一个函数模板,使其实例化,产生一个匹配的模板函数,若找到了,就调用它。......
2023-11-07
声明函数模板的一般格式如下:template<模板参数表>函数返回值类型函数模板名(形参表)函数模板定义由关键字template开头,表示声明一个模板。模板参数表写在尖括号<>中,参数一般由关键字class或typename后加一个标识符构成。Class和typename的意义相同,表示后面的标识符是一个参数类型,代表一个潜在的标准类型或用户定义的类型。例如,定义max函数模板求两个数中的较大者。如下面的声明是错误的:可以看出,用函数模板比函数重载更方便,程序更简洁。......
2023-11-07
相关推荐