发布日期:2015-12-29 10:04 来源: 标签: 编程语言 C++教程 C++派生类 C++构造函数
继承体系中对象实例的构造有着一定的执行顺序,主要针对派生类对象实例构造时,基类构造以及派生类构造函数的执行情况作详细讲述。下面我们就做一下具体讲解,希望大家多多支持中国站长网络学院。
      继承体系中对象实例的构造有着一定的执行顺序,主要针对派生类对象实例构造时,基类构造以及派生类构造函数的执行情况作详细讲述。下面通过一个派生类对象构造实例作为开端。
1.准备实例
      打开UE工具,创建新的空文件并且另存为chapter1005_01.h、chapter1005_01.cpp、chapter1005_02.h、chapter1005_02.cpp。该代码文件随后会同makefile文件一起通过FTP工具传输至Linux服务器端,客户端通过scrt工具访问操作。程序代码文件编辑如下所示。
//水果类头文件chapter1005_01.h
#include <iostream>
using namespace std;
class Fruit
{
         public:
                   Fruit();
                   voidshowFruitInfo();
};
//水果类源文件chapter1005_01.cpp
#include "chapter1005_01.h"
Fruit::Fruit()
{
         cout<<"Fruitclass construction!"<<endl;
}
void Fruit::showFruitInfo()
{
         cout<<"Thisis Fruit class!"<<endl;
}
//苹果类头文件chapter1005_02.h
#include "chapter1005_01.h"
class Apple: public Fruit
{
         public:
                   Apple();
                   ~Apple(){}
};
//苹果类源文件chapter1005_02.cpp
#include "chapter1005_02.h"
Apple::Apple()
{
         cout<<"Appleclass construction!"<<endl;
}
int main()
{
         Fruitfruit;
         Appleapple;
         apple.showFruitInfo();
         return0;
}
本实例主要通过水果类继承方式演示继承体系中构造函数执行顺序情况。程序主要由主函数与水果、苹果类组成。程序具体剖析见程序注释与后面的讲解。
2.编辑makefile
Linux平台下需要编译源文件为chapter1005_01.cpp、chapter1005_02.cpp,相关makefile工程文件编译命令编辑如下所示。
OBJECTS=chapter1005_01.o chapter1005_02.o
CC=g++
Apple: $(OBJECTS)
       $(CC)$(OBJECTS) -o Apple
chapter1005_01.o: chapter1005_01.h
chapter1005_02.o: chapter1005_02.h
clean:
      rm-f Apple core $(OBJECTS)
submit:
       cp-f -r Apple ../bin
       cp-f -r *.h ../include
上述makefile文件套用前面的模板格式,主要替换了代码文件、程序编译中间文件、可执行程序等。在编译命令部分-g选项的加入,表明程序编译同时加入了可调式信息。
3.编译运行程序
当前shell下执行make命令,生成可执行程序文件,随后通过make submit命令提交程序文件至本实例bin目录,通过cd命令定位至实例bin目录,执行该程序文件运行结果如下所示。
[billing@localhost src]$ make
g++    -c -ochapter1005_01.o chapter1005_01.cpp
g++    -c -ochapter1005_02.o chapter1005_02.cpp
g++ chapter1005_01.o chapter1005_02.o -o Apple
[billing@localhost src]$ make submit
cp -f -r Apple ../bin
cp -f -r *.h ../include
[billing@localhost src]$ cd ../bin
[billing@localhost bin]$ ./Apple
Fruit class construction!
Fruit class construction!
Apple class construction!
      本实例共涉及两个类,即水果类与其派生类苹果类。其中水果类除了包含有自身的构造函数外还拥有一个打印本身类信息成员方法。其派生类Apple中,只拥有属于自身一个构造函数定义,另外就是继承至水果类的打印方法成员。
      主程序中首先定义水果类对象实例,此时根据类构造规则如果没有自定义构造函数,则调用默认构造来构造对象实例。而此处基类自定义了构造函数,则调用自定义构造函数,该函数中执行体只有打印其执行构造的信息“Fruit class construction!”。
      随后定义派生类对象,此时注意到,派生类对象实例构造会同时调用基类构造函数与派生类自身的构造函数,并且基类构造函数首先被执行,所以会先调用基类构造函数打印“Fruit class construction!”随后调用派生类构造函数打印信息“Apple class construction!”。最终调用继承至基类的打印类信息方法打印信息“This is Fruit class”从而结束程序运行。
      从上述实例表明,基类对象构造时保持类构造特性,而派生类对象实例构造时会优先调用基类构造函数。原因在于派生类中继承有基类的成员,派生类对象构造时需要优先构造初始化基类成员以供派生类使用。派生类对象实例构造时,优先处理基类构造函数,如果基类没有自定义构造函数则直接调用其默认构造即可。另外基类的构造函数可以由派生类单独显式调用,上述实例修改如下所示。
1.准备实例
      打开UE工具,创建新的空文件并且另存为chapter1006_01.h、chapter1006_01.cpp、chapter1006_02.h、chapter1006_02.cpp。该代码文件随后会同makefile文件一起通过FTP工具传输至Linux服务器端,客户端通过scrt工具访问操作。程序代码文件编辑如下所示。
//水果类头文件chapter1006_01.h
#include <iostream>
using namespace std;
class Fruit                                                                                              //水果类Fruit定义
{
         public:
                   Fruit(intid,string name);                                         //水果类构造函数,两个整型参数
         protected:
                   intm_id;                                                                    //水果类保护数据成员,表示水果编号
                   stringm_name;                                                                 //水果类保护数据成员,表示水果名称
};
//水果类源文件chapter1006_01.cpp
#include "chapter1006_01.h"
Fruit::Fruit(int id,string name)                                                   //水果类构造函数定义
{
         m_id= id;
         m_name= name;
         cout<<"Fruitclass construction!"<<endl;
}
//苹果类头文件chapter1006_02.h
#include "chapter1006_01.h"
class Apple: public Fruit                                                            //继承至水果类的苹果类Apple定义
{
   public:
                   Apple(intid,string name,int price);                       //苹果类构造函数
                   ~Apple(){}                                                                           //苹果类析构函数
                   voidshowAppleInfo();                                            //打印苹果类信息函数
         protected:
                   intm_price;                                                               //苹果类保护数据成员,表示苹果价格
};
//苹果类源文件chapter1006_02.cpp
#include "chapter1006_02.h"
Apple::Apple(int id,string name,int price)                              //苹果类构造函数定义
         :Fruit(id,name)
{
         m_price= price;
         cout<<"Appleclass construction!"<<endl;
}
void Apple::showAppleInfo()                                                   //打印苹果类函数定义
{
         cout<<"Fruitid:"<<m_id<<endl;
         cout<<"Fruitname:"<<m_name<<endl;
         cout<<"Fruitprice:"<<m_price<<endl;
}
int main()
{
         Fruitfruit(1,"Fruit");                                                            //定义水果类对象实例,同时传入实参初始化
         Appleapple(2,"Apple",3);                                                //定义苹果类对象实例,同时传入实参初始化
         apple.showAppleInfo();                                                   //调用apple对象实例打印方法显示信息
         return0;
}
本实例主要通过水果类继承方式演示继承体系中构造函数执行顺序情况。程序主要由主函数与水果、苹果类组成。程序具体剖析见程序注释与后面的讲解。
2.编辑makefile
Linux平台下其makefile编译文件中涉及两个头文件以及两个源代码文件,makefile文件编辑如下。
OBJECTS=Fruit.o Apple.o
CC=g++
Apple: $(OBJECTS)
       $(CC)$(OBJECTS) -o Apple
Fruit.o: Fruit.h
Apple.o: Apple.h
clean:
       rm-f Apple core $(OBJECTS)
上述makefile文件套用前面的模板格式,主要替换了代码文件、程序编译中间文件、可执行程序等。在编译命令部分-g选项的加入,表明程序编译同时加入了可调式信息。
3.编译运行程序
当前shell下执行make命令,生成可执行程序文件,随后通过make submit命令提交程序文件至本实例bin目录,通过cd命令定位至实例bin目录,执行该程序文件运行结果如下所示。
[developer @localhost src]$ make
g++    -c -ochapter1006_01.o chapter1006_01.cpp
g++    -c -ochapter1006_02.o chapter1006_02.cpp
g++ chapter1006_01.o chapter1006_02.o -o Apple
[developer @localhost src]$ make submit
cp -f -r Apple ../bin
cp -f -r *.h ../include
[developer @localhost src]$ cd ../bin
[developer @localhost bin]$ ./Apple
Fruit class construction!
Fruit class construction!
Apple class construction!
Fruit id:2
Fruit name:Apple
Fruit price:3
      经过修改的实例中主要增加了基类的保护型数据成员以及自定义构造函数。其中,构造函数涉及两个基类成员的初始化工作。两个数据成员m_id与m_name分别表示水果类的编号与名称,构造函数定义中主要依据外界传入参数来初始化该数据成员。派生类中则除了继承至基类的保护型数据成员外,增加一个m_price数据成员表示水果的价格,同样其构造函数中实现根据参数传递初始化该值。
      所不同的是,在派生类Apple构造函数定义中,增加了显示调用基类构造函数的操作,通过“:”初始化参数列表的方式来调用基类的构造函数。同时将根据调用派生类构造函数传入的实参来作为基类构造函数实参初始化。主程序中首先定义Fruit类对象实例fruit,同时传入编号以及名称值构造并初始化对象实例。随后定义派生类对象apple,此时传入三个实参用来构造初始化,其中,前两个参数用于显式调用基类构造函数作为实参传入并初始化。最后在派生类中增加打印基类以及派生类所有保护数据成员信息,验证构造初始化工作的正确性。
      综上所述,继承体系中派生类构造对象实例时。首先调用基类的构造函数用于初始化基类成员。当基类没有自定义构造函数时,调用其默认构造函数。同时基类有多个构造函数重载时也可以在派生类中显式的指定调用基类哪个构造函数来构造对象实例。

相关评论

专题信息
    C++是在C语言的基础上开发的一种面向对象编程语言,应用广泛。C++支持多种编程范式 --面向对象编程、泛型编程和过程化编程。最新正式标准C++于2014年8月18日公布。 其编程领域众广,常用于系统开发,引擎开发等应用领域,是至今为止最受广大程序员受用的最强大编程语言之一,支持类:类、封装、重载等特性! 本教程从基础讲解了C++语言,希望对大家有所帮助,望多多支持中国站长网络学院。