当定义类对象时,构造函数会自动执行。因为一个类可能会有包括默认构造函数在内的不止一种构造函数,下面讨论如何调用特定的构造函数。在这种情况下,会执行默认的构造函数,从而将sa的数据成员初始化为0。如果参数的类型和顺序不与任何构造函数相匹配,则C++将使用类型转换并寻找最佳匹配。......
2023-11-07
从基类派生子类时,基类的构造函数不能够继承到派生类中,因此,派生类的构造函数必须通过调用基类的构造函数来初始化基类子对象。所以,在定义派生类的构造函数时除了对自己的数据成员进行初始化外,还必须负责调用基类构造函数使基类的数据成员得以初始化。如果派生类中还有子对象,还应包含对子对象初始化的构造函数。
派生类构造函数的一般语法格式如下:
这里,派生类的构造函数名与类名相同。在构造函数的参数表中,给出了初始化基类数据、新增对象数据及新增一般成员数据所需要的全部参数。在参数表之后,列出需要使用参数进行初始化的基类名和子对象名及各自的参数表,各项之间使用逗号分隔。这里基类名、子对象名之间的次序无关紧要,它们各自出现的顺序可以是任意的。在生成派生类对象时,系统首先会使用这里列出的参数,来调用基类和子对象的构造函数。
派生类构造函数执行的一般次序如下:
(1)最先调用基类的构造函数,多个基类则按派生类声明时列出的次序、从左到右调用,而不是初始化列表中的次序。
(2)再次调用对象成员(子对象)的构造函数,按类声明中对象成员出现的次序调用,而不是初始化列表中的次序。
(3)最后执行派生类的构造函数。
其中,如果派生类新增成员中有某个类的子对象,第(2)步的调用才会执行,否则就直接跳转到第(3)步,执行派生类的构造函数。
【例6.5】分析以下程序的执行结果。
解:上述程序中,类B是类A的派生类(属单继承的情况),它的构造函数B的冒号后面是成员初始化列表,如果该表中有多项,它们之间用逗号分隔。该成员初始化列表的顺序是:先是基类A构造函数;再是派生类B中子对象类的构造函数;最后是派生类B的构造函数。程序的执行结果如下:
A Constructor2
B Constructor2
x1=22
x2=12
在实际应用中,使用派生类构造函数时应注意如下两个问题:
(1)派生类构造函数的定义中可以省略对基类构造函数的调用,其条件是在基类中必须有默认的构造函数或者根本没有构造函数。
(2)当基类的构造函数使用一个或多个参数时,则派生类必须定义构造函数,提供将参数传递给基类构造函数的途径。在某些情况下,派生类构造函数的函数体可能为空,仅起到参数传递作用。(www.chuimin.cn)
【例6.6】分析以下程序的执行结果。
解:上述程序中,由A和B两个类派生出类C(属多继承的情况),在指定派生的语句中,B在前,A在后,所以先调用B的构造函数,后调用A的构造函数。程序的执行结果如下:
B Constructor
A Constructor
C Constructor
a=3
b=7
c=5
若基类和派生类都包含其他类的对象,在创建派生类的对象时,首先执行基类成员对象的构造函数,然后执行基类的构造函数,再执行派生类成员对象的构造函数,执行派生类的构造函数。析构函数是按照对应的构造函数调用的相反顺序来调用的。
【例6.7】分析以下程序的执行结果。
解:程序执行结果如下:
classs A
classs C
classs B
classs D
上述程序中,由类C派生出类D,但类C中包含一个类A的对象a,类D中包含一个类B的对象b。所以,对于main()函数中的语句D d,先执行基类C中对象a的构造函数,再执行基类C的构造函数,接着是类D中对象b的构造函数,最后执行类D的构造函数。
有关C++程序设计基础教程的文章
当定义类对象时,构造函数会自动执行。因为一个类可能会有包括默认构造函数在内的不止一种构造函数,下面讨论如何调用特定的构造函数。在这种情况下,会执行默认的构造函数,从而将sa的数据成员初始化为0。如果参数的类型和顺序不与任何构造函数相匹配,则C++将使用类型转换并寻找最佳匹配。......
2023-11-07
为此,C++提供了一个更好的方法,就是利用类的构造函数来初始化类的数据成员。构造函数具有如下几个特点:构造函数名与类名相同,且没有返回值,不能指定函数类型。构造函数通常被声明为公有属性,但它不能像其他成员函数那样被显式地调用,它是在创建对象时被系统自动调用的。例如,可以将例2.1的MyClass类扩展为MyClass2,使其包含两个构造函数:上述类中包含两个构造函数:一个没有参数,另一个有两个参数。......
2023-11-07
内联函数不能是虚函数,因为内联函数是不能在运行中动态确定其位置的。即使虚函数在类的内部定义,编译时仍将其看作是非内联的。声明虚析构函数的目的在于:使用delete运算符删除一个对象时,能确保析构函数被正确地执行。如果不相同,则被派生类虚函数的参数类型强制转换为基类中虚函数的参数类型。......
2023-11-07
声明函数模板的一般格式如下:template<模板参数表>函数返回值类型函数模板名(形参表)函数模板定义由关键字template开头,表示声明一个模板。模板参数表写在尖括号<>中,参数一般由关键字class或typename后加一个标识符构成。Class和typename的意义相同,表示后面的标识符是一个参数类型,代表一个潜在的标准类型或用户定义的类型。例如,定义max函数模板求两个数中的较大者。如下面的声明是错误的:可以看出,用函数模板比函数重载更方便,程序更简洁。......
2023-11-07
和构造函数一样,析构函数也不能被继承,因此在执行派生类的析构函数时,基类的析构函数也将被调用,其顺序与执行构造函数时的顺序正好相反。最后调用基类的析构函数,多个基类则按派生类声明时列出的逆序、从右到左调用,而不是初始化列表中的次序。首先执行派生类的析构函数,然后执行派生类成员对象的析构函数,再执行基类的析构函数,最后执行基类成员对象的析构函数。......
2023-11-07
静态成员函数与静态数据成员类似,也是属于类的。与一般成员函数类似,静态成员函数也有访问限制,私有静态成员函数不能由外界访问。解:本程序的执行结果如下:s=5程序中定义对象a时,通过构造函数使静态数据成员n=2,在定义对象b时,通过构造函数使静态数据成员n=5,再执行MyClass2∷add()语句使全局变量s=5。这样共执行构造函数5次,n累计为5。......
2023-11-07
声明虚函数的一般格式如下:virtual函数类型函数名(参数表)其中,用关键词virtual声明的函数称为虚函数。如果一个成员函数被声明为虚函数,这就意味着该成员函数在派生类中可能有不同的实现。动态绑定只能通过指针或引用标识对象来调用虚函数。......
2023-11-07
程序的执行结果如下:Point复制构造函数被调用Point复制构造函数被调用Point复制构造函数被调用Point复制构造函数被调用Distance构造函数被调用(1,2)和(8,6)两个点的距离:8.06226......
2023-11-07
相关推荐