已阅读5页,还剩82页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第8章 多态性,8.1 多态性概述 8.2 运算符重载 8.3 虚函数 8.4 抽象类,8.1 多态性概述,所谓多态性是指同一个接口可以通过多种方法调用,如图8-1所示。通俗地说,多态性是指用一个相同的名字定义不同的函数,这些函数的执行过程不同,但是有相似的操作,即用同样的接口访问不同的函数。比如,一个对象中有很多求两个数中最大值的行为,虽然可以针对不同的数据类型,写很多不同名称的函数来实现,但事实上,它们的功能几乎完全相同。这时,就可以利用多态的特征,用统一的标识来完成这些功能。,图8-1 多态性为用户提供单一接口示意图,面向对象的多态性从实现的角度来讲,可以分为静态多态性和动态多态性两种。静态多态性是在编译的过程中确定同名操作的具体操作对象的,而动态多态性则是在程序运行 过程中动态地确定操作所针对的具体对象的。这种确定操作具体对象的过程就是联编(binding),也称为绑定。联编是指计算机程序自身彼此关联的过程。也就是把一个标识符名和一个存储地址联系在一起的过程。用面向对象的术语讲,就是把一条消息和一个对象的方法相结合的过程。,所谓消息,是指对类的成员函数的调用。不同的方法是指不同的实现,也就是调用了不同的函数。按照联编进行阶段的不同,联编方法可以分为两种:静态联编和动态联编。这两种联编过程分别对应着多态的两种实现方式。联编工作在编译连接阶段完成的情况称为静态联编。在编译、连接过程中,系统就可以根据类型匹配等特征确定程序中操作调用与执行该操作的代码的关系,即确定某一个同名标识到底是要调用哪一段程序代码。函数重载和运算符重载就属于静态多态性。,和静态联编相对应,如果联编工作在程序运行阶段完成,则称为动态联编。在编译、连接过程中无法解决的联编问题,要等到程序开始运行之后再来确定。例如,本章将要介绍的虚函数就是通过动态联编完成的。 函数重载在函数及类的章节中曾做过详细的讨论,所以在本章中,静态多态性主要介绍运算符重载;对于动态多态性,将对虚函数作详细介绍。,8.2 运算符重载,C+中预定义的运算符的操作对象只能是基本数据类型。实际上,对于很多用户自定义的类型(如类),也需要有类似的运算操作。例如,下面的程序声明了一个点类point。 classpoint /point类声明 private: intx,y;,public: /构造函数 point(intxx=0,intyy=0)x=xx;y=yy; intget_x(); /显示x值 intget_y(); /显示y值 /. ;,于是我们可以这样声明点类的对象: pointp1(1,1),p2(3,3) 如果我们需要对p1和p2进行加法运算,该如何实现呢?我们当然希望能使用“+”运算符,写出表达式“p1+p2”,但是编译的时候却会出错,因为编译器不知道该如何完成这个加法。这时候,我们就需要自己编写程序来说明“+”在作用于point类对象时,该实现什么样的功能,这就是运算符重载。运算符重载是对已有的运算符赋予多重含义,使同一个运算符作用于不同类型的数据时,导致不同类型的行为。,在运算符重载的实现过程中,首先把指定的运算表达式转化为对运算符函数的调用,运算对象转化为运算符函数的实参,然后,根据实参的类型来确定需要调用的函数。这个过程是在编译过程中完成的。,8.2.1 运算符重载的规则 运算符是在C+系统内部定义的,它们具有特定的语法规则,如参数说明、运算顺序、优先级别等。因此,运算符重载时必须要遵守一定的规则。 C+中的运算符除了少数几个(类属关系运算符“.”、作用域分辨符“:”、成员指针运算符“*”、sizeof运算符和三目运算符“?:”)之外,全部可以重载,而且只能重载C+中已有的运算符,不能臆造新的运算符。,重载之后运算符的优先级和结合性都不能改变,也不能改变运算符的语法结构,即单目运算符只能重载为单目运算符,双目运算符只能重载为双目运算符。 运算符重载后的功能应当与原有功能相类似。 重载运算符含义必须清楚,不能有二义性。 运算符的重载形式有两种:重载为类的成员函数和重载为类的友元函数。,运算符重载为类的成员函数的一般语法形式如下: operator(形参表) 函数体; 运算符重载为类的友元函数的一般语法形式如下: friendoperator(形参表) 函数体; ,其中: 函数类型指定了重载运算符的返回值类型,也就是运算结果类型。 operator是定义运算符重载函数的关键字。 运算符是要重载的运算符名称。 形参表给出重载运算符所需要的参数和类型。 friend是对于运算符重载为友元函数时,在函数类型说明之前使用的关键字。,特别需要注意的是,当运算符重载为类的成员函数时,函数的参数个数比原来的操作数个数要少一个(后置“+”、“-”除外);当重载为类的友元函数时,参数个数与原操作数的个数相同。原因是重载为类的成员函数时,如果某个对象使用重载了的成员函数,自身的数据可以直接访问,就不需要再放在参数表中进行传递,少了的操作数就是该对象本身。,8.2.2 运算符重载为成员函数 运算符重载实质上就是函数重载,当运算符重载为成员函数之后,它就可以自由地访问本类的数据成员了。实际使用时,总是通过该类的某个对象来访问重载的运算符。如果是双目运算符,一个操作数是对象本身的数据,由this指针指出,另一个操作数则需要通过运算符重载函数的参数表来传递;如果是单目运算符,操作数由对象的this指针给出,就不再需要任何参数。下面分别介绍这两种情况。,1双目运算:oprdlBoprd2 对于双目运算符B,如果要重载B为类的成员函数,使之能够实现表达式oprdlBoprd2(其中oprdl为A类的对象),则应当把B重载为A类的成员函数,该函数只有一个形参,形参的类型是oprd2所属的类型。经过重载之后,表达式oprdlBoprd2就相当于函数调用oprdl.operatorB(oprd2)。,2单目运算 1)前置单目运算:Uoprd 对于前置单目运算符U,如“-”(负号)、“+”等,如果要重载U为类的成员函数,用来实现表达式Uoprd(其中oprd为A类的对象),则U应当重载为A类的成员函数,函数没有形参。经过重载之后,表达式Uoprd相当于函数调用oprd.operatorU()。 例如,前置单目运算符“+”重载的语法形式如下: operator+(); 使用前置单目运算符“+”的语法形式如下: +;,2) 后置单目运算:oprdV 再来看后置运算符V,如“+”和“-”,如果要将它们重载为类的成员函数,用来实现表达式oprd+或oprd-(其中oprd为A类的对象),那么运算符就应当重载为A类的成员函数,这时函数要带有一个整型(int)形参。重载之后,表达式oprd+和oprd-就相当于函数调用oprd.operator+(0)和oprd.operator-(0)。 例如,后置单目运算符“+”重载的语法形式如下: operator+(int); 使用后置单目运算符“+”的语法形式如下: +;,【例8-1】双目运算符重载为成员函数例题。 本例题重载二维点point加减法运算(关于二维点point类的定义在前面章节中已介绍过),将一个双目运算符重载为成员函数。point的加减法是x和y分别相加减,运算符的两个操作数都是point类的对象,因此,可以把“+”、“-”运算符重载为point类的成员函数,重载函数只有一个形参,类型同样也是point类对象。,#include classpoint private: floatx,y; public: point(floatxx=0,floatyy=0)x=xx;y=yy; floatget_x()returnx; floatget_y()returny;,pointoperator+(pointp1); /重载运算符“+” pointoperator-(pointp1); /和“-”为成员函数 ; pointpoint:operator+(pointq) returnpoint(x+q.x,y+q.y); pointpoint:operator-(pointq) returnpoint(x-q.x,y-q.y); voidmain(), pointp1(3,3),p2(2,2),p3,p4; /声明point类的对象 p3=p1+p2; /两点相加 p4=p1-p2; /两点相减 cout“p1+p2:x=“p3.get_x()“,y=“p3.get_y()endl; cout“p1-p2:x=“p4.get_x()“,y=“p4.get_y()endl; ,在本例中,将point的加减法运算重载为point类的成员函数。可以看出,除了在函数声明及实现的时候使用了关键字operator之外,运算符重载成员函数与类的普通成员函数没有什么区别。在使用的时候,可以直接通过运算符、操作数的方式来完成函数调用。这时,运算符“+”、“-”原有的功能都不改变,对整型数、浮点数等基本类型数据的运算仍然遵循C+预定义的规则,同时添加了新的针对point运算的功能。“+”这个运算符,作用于不同的对象就会导致完全不同的操作行为,具有了更广泛的多态特征。,本例中重载的“+”、“-”函数中,都是创建一个临时的无名对象作为返回值: returnpoint(x+q.x,y+q.y); 这表面上看起来像是对构造函数的调用,但其实并非如此。这是临时对象语法,它的含义是创建一个临时对象并返回它。当然,也可以按如下形式返回函数值: pointpoint:operator+(pointq) pointp; p.x=x+q.x;,p.y=y+q.y; returnp; pointpoint:operator-(pointq) pointp; p.x=x-q.x; p.y=y-q.y; returnp; ,这两种方法的执行效率是完全不同的。后者的执行过程是这样的:创建一个局部对象p(这时会调用构造函数),执行return语句时,会调用拷贝构造函数,将p的值拷贝到主调函数中的一个无名临时对象中。当函数operator+结束时,会调用析构函数析构对象p,然后p消亡。两种方法相比,前一种方法的效率高,因为它是直接将一个无名临时对象创建到主调函数中。 例8-1的程序运行结果为 p1+p2:x=5,y=5 p1-p2:x=1,y=1,【例8-2】单目运算符重载为成员函数例题。 本程序为时钟计时程序。在程序中将单目运算符重载为类的成员函数,单目运算符前置“+”和后置“+”的操作数是时钟类的对象,可以把这些运算符重载为时钟类的成员函数。对于前置单目运算符,重载函数没有形参;对于后置单目运算符,重载函数有一个整数形参。本例中,我们把自增前置“+”和自减前置“-”运算重载为point类的成员函数。,#include classpoint private: floatx,y; public: point(floatxx=0,floatyy=0)x=xx;y=yy; floatget_x()returnx; floatget_y()returny;,pointoperator+(); /重载前置运算符“+” pointoperator-(); /重载前置运算符“-” ; pointpoint:operator+() if(x640)+x; if(y480)+y; return*this; ,pointpoint:operator-() if(x0)-x; if(y0)-y; return*this; voidmain() pointp1(10,10),p2(200,200); /声明point类的对象 for(inti=0;i5;i+) ,cout“p1:x=“p1.get_x()“,y=“p1.get_y()endl; +p1; for(i=0;i5;i+) cout“p2:x=“p2.get_x()“,y=“p2.get_y()endl; -p2; ,程序运行结果为 p1:x=10,y=10 p1:x=11,y=11 p1:x=12,y=12 p1:x=13,y=13 p1:x=14,y=14 p2:x=200,y=200 p2:x=199,y=199 p2:x=198,y=198 p2:x=197,y=197 p2:x=196,y=196,前置单目运算符和后置单目运算符重载的最主要的区别就在于重载函数的形参。语法规定,前置单目运算符重载为成员函数时没有形参,而后置单目运算符重载为成员函数时,需要有一个int型形参。这个int型参数在函数体中并不使用,纯粹是用来区别前置与后置,因此,参数表中可以只给出类型名,没有参数名。,8.2.3 运算符重载为友元函数 运算符也可以重载为类的友元函数,这样它就可以自由地访问该类的任何数据成员。这时,运算所需要的操作数都需要通过函数的形参表来传递,在参数表中形参从左到右的顺序就是运算符操作数的顺序。但是,有些运算符不能重载为友元,如“=”、“()”、“”和“-”。,1双目运算:oprdlBoprd2 对于双目运算符B,如果oprdl为A类的对象,则应当把B重载为A类的友元函数,该函数有两个形参,其中一个形参的类型是A类。经过重载之后,表达式oprdlBoprd2就相当于函数调用operatorB(oprdl,oprd2)。,2单目运算 1)前置单目运算:Uoprd 对于前置单目运算符U,如“-”(负号)等,如果要实现表达式Uoprd(其中oprd为A类的对象),则U可以重载为A类的友元函数,函数的形参为A类的对象。经过重载之后,表达式Uoprd相当于函数调用operatorU(oprd)。,2)后置单目运算:oprdV 对于后置运算符V,如“+”和“-”,如果要实现表达式oprd+或oprd-(其中oprd为A类的对象),那么运算符就可以重载为A类的友元函数,这时函数的形参有两个,一个是A类的对象oprd,另一个是整型(int)形参。重载之后,表达式oprd+和oprd-就相当于函数调用operator+(oprd,0)和operator-(oprd,0)。,【例8-3】双目运算符重载为友元重载例题。 本例题用运算符重载为友元函数的方法重做两点加减法运算。 #include classpoint private: floatx,y; public:,point(floatxx=0,floatyy=0)x=xx;y=yy; floatget_x()returnx; floatget_y()returny; friendpointoperator+(pointp1,pointp2); /重载运算符“+” friendpointoperator-(pointp1,pointp2); /和“-”为友元函数 ; pointoperator+(pointp1,pointp2) ,returnpoint(p1.x+p2.x,p1.y+p2.y); pointoperator-(pointp1,pointp2) returnpoint(p1.x-p2.x,p1.y-p2.y); voidmain() ,pointp1(3,3),p2(2,2),p3,p4; /声明point类的对象 p3=p1+p2; /两点相加 p4=p1-p2; /两点相减 cout“p1+p2:x=“p3.get_x()“,y=“p3.get_y()endl; cout“p1-p2:x=“p4.get_x()“,y=“p4.get_y()endl; 从上述程序可以看到,将运算符重载为类的友元函数时,必须把操作数全部通过形参的方式传递给运算符重载函数。和例8-1相比,本例题的主函数根本没有做任何改动,主要的变化在point类的成员,程序运行的结果完全相同。,8.2.4 其它运算符重载 前面介绍了一些简单运算符的重载,除此之外,还有以下运算符也常被重载。 比较运算符重载(如,=,=,!=)。 赋值运算符重载(如=,+=,-=,*=,/=)。 下标运算符“”重载。 下标运算符“”通常用于取数组中的某个元素,通过下标运算符重载,可以实现数组下标的越界检测等。,运算符new和delete重载。 通过重载new和delete,可以克服new和delete的不足,使其按要求完成对内存的管理。 逗号运算符“,”重载。 逗号运算符是一个双目运算符,和其它运算符一样,我们也可以通过重载逗号运算符来达到期望的结果。逗号运算符构成的表达式为“左操作数,右操作数”,该表达式返回右操作数的值。,8.3 虚函数,8.3.1为什么要引入虚函数 为什么要引入虚函数,我们来看一个例子。 【例8-4】没有使用虚函数的例题。 #include classbase /定义基类base public:,voidwho() cout“thisistheclassofbase!“endl; ; classderive1:publicbase /定义派生类derive1 public: voidwho() cout“thisistheclassofderive1!“endl; ; classderive2:publicbase /定义派生类derive2,public: voidwho() coutwho();,ptr= 此例在main()函数中定义了一个基类对象obj,和两个派生类对象obj1与obj2,又定义了一个指向基类对象的指针ptr。,此程序的意图是用ptr指针分别指向不同的对象,以便执行不同对象所对应的类的成员函数。当ptr指向obj对象时,ptr-who()调用base类的成员函数who();当ptr指向obj1对象时,我们希望ptr-who()调用derive1类的成员函数who();而当ptr指向obj2对象时,则希望ptr-who()调用derive2类的成员函数who()。此程序执行后实际得到的结果为,thisistheclassofbase! (a) thisistheclassofbase! (b) thisistheclassofbase! (c) thisistheclassofderive1! (d) thisistheclassofderive2! (e),在运行结果中,(a)、(d)和(e)与所预想的相符,而(b)和(c)却不是希望得到的。这说明,不管指针ptr当前指向哪个对象(是基类对象还是派生类对象),ptr-who()调用的都是基类中定义的who()函数。也就是说,通过指针引起的普通成员函数调用,仅仅与指针的类型有关,而与指针正指向什么对象无关。在这种情况下,必须采用显式的方式调用派生类的函数成员。,例如: obj1.who()或obj2.who() 或者是采用对指针的强制类型转换的方法,例如: (derive1*)ptr)-who()或(derive2*)ptr)-who() 本来使用对象指针是为了表达一种动态的性质,即当指针指向不同对象时执行不同的操作,现在看来并没有起到这种作用。要实现这种功能,就需要引入虚函数的概念。这里,只需将基类的who()函数声明为虚函数即可。,8.3.2 虚函数的定义及使用 1.虚函数的定义 虚函数的定义是在基类中进行的。它是在基类中需要定义为虚函数的成员函数的声明中冠以关键字virtual。当基类中的某个成员函数被声明为虚函数后,此虚函数就可以在一个或多个派生类中被重新定义,在派生类中重新定义时,其函数原型,包括返回类型、函数名、参数个数、参数类型以及参数的顺序都必须与基类中的原型完全相同。,一般虚函数的定义语法如下: virtual(形参表) 函数体 其中,被关键字virtual说明的函数为虚函数。特别要注意的是,虚函数的声明只能出现在类声明中的函数原型声明中,而不能出现在成员的函数体实现的时候。,需要注意,动态联编只能通过成员函数来调用或者通过指针、引用来访问虚函数。如果使用对象名的形式访问虚函数,则将采用静态联编方式调用虚函数,而无需在运行过程中进行调用。下面是通过指针访问虚函数的例题。,【例8-5】使用虚函数例题。 #include classbase /定义基类base public: virtualvoidwho() /虚函数声明 cout“thisistheclassofbase!“endl; ;,classderive1:publicbase /定义基类派生类derive1 public: voidwho() /重新定义虚函数 cout“thisistheclassofderive1!“endl; ; classderive2:publicbase /定义派生类derive2 public:,voidwho() /重新定义虚函数 coutwho();,ptr= 此时,程序运行结果为 thisistheclassofbase! thisistheclassofderive1! thisistheclassofderive2!,分析一下上面这个程序,在基类中对voidwho()进行了虚函数声明,这样,在其派生类中就可以重新定义它。在派生类derive1和derive2中分别重新定义voidwho()函数,注意,此虚函数在派生类中重新定义时不再需要virtual声明,此声明只在其基类中出现一次。在voidwho()函数被重新定义时,其函数的原型与基类中的函数原型必须完全相同。,在main()函数中,定义了一个指向基类类型的指针,它也被允许指向其派生类。在执行过程中,不断改变它所指向的对象,ptr-who()就能调用不同的版本。虽然都是ptr-who()语句,但是,当ptr指向不同的对象时,所对应的执行动作就不同。由此可见,用虚函数充分体现了多态性。并且,因为ptr指针指向哪个对象是在执行过程中确定的,所以体现的又是一种动态的多态性。,2. 虚函数与重载的关系 在一个派生类中重新定义基类的虚函数是函数重载的另一种特殊形式,但它不同于一般的函数重载。 一般的函数重载,只要函数名相同即可,函数的返回类型及所带的参数可以不同。但当重载一个虚函数时,也就是说在派生类中重新定义此虚函数时,要求函数名、返回类型、参数个数、参数类型以及参数的顺序都与基类中的原型完全相同,不能有任何的不同。,3多继承中的虚函数 在多继承中由于派生类是由多个基类派生而来的,因此,虚函数的使用就不像单继承那样简单。请看下面的例题。 【例8-6】多继承中使用虚函数例题。 #include classbase1 /定义基类base1 public: virtualvoidwho() /函数who()为虚函数,cout“thisistheclassofbase1!“endl; ; classbase2 /定义基类base2 public: voidwho() /此函数who()为一般的函数 cout“thisistheclassofbase2!“endl; ; classderive:publicbase1,publicbase2 ,public: voidwho() cout“thisistheclassofderive!“endl; ; main() base1obj1,*ptr1; base2obj2,*ptr2; deriveobj3;,ptr1= ,此时,程序执行的结果为 thisistheclassofbase1! thisistheclassofbase2! thisistheclassofderive! thisistheclassofbase2! 从上面的例子看出,派生类derive中的函数who()在不同的场合呈现不同的性质。如相对base1路径,由于在base1中的who()函数前有关键字virtual,所以它是一个虚函数;若相对于base2派生路径,在base2中的who()函数为一般函数,所以,此时它只是一个重载函数。,当base1类指针指向derive类对象obj3时,函数who()就呈现出虚特性;当base2类指针指向derive类对象obj3时,函数只呈现一般的重载特性。 若一个派生类,它的多个基类中有公共的基类,在公共基类中定义一个虚函数,则多重派生以后仍可以重新定义虚函数,也就是说,虚特性是可以传递的。请看下面的例题。,【例8-7】多继承中虚特性的传递例题。 #include classbase /定义基类base public: virtualvoidwho() /定义虚函数 cout“thisistheclassofbase!“endl; ; classbase1:publicbase /定义派生类base1, public: voidwho() cout“thisistheclassofbase1!“endl; ; classbase2:publicbase /定义派生类类base2 public: voidwho() cout“thisistheclassofbase2!“endl; ;,classderive:publicbase1,publicbase2 /定义派生类derive public: voidwho() cout“thisistheclassofderive!“endl; ; main() base1*ptr1; base2*ptr2;,deriveobj; ptr1= 此时,程序执行的结果为 thisistheclassofderive! thisistheclassofderive!,从本例题可以看出,虚特性是可以传递的。base类作为base1和base2类的直接基类,它的成员函数who()被声明为虚函数,则base1和base2类中的who()都具有虚特性,即均为虚函数;而derive类为base1和base2类的派生类,因此,它的成员函数who()也为虚函数。,8.3.3 虚函数的限制 如果我们将所有的成员函数都设置为虚函数,当然是很有益的。它除了会增加一些额外的资源开销,没有什么坏处。但设置虚函数须注意以下几点。 只有成员函数才能声明为虚函数。因为虚函数仅适用于有继承关系的类对象,所以普通函数不能声明为虚函数。,虚函数必须是非静态成员函数。这是因为静态成员函数不受限于某个对象。 内联函数不能声明为虚函数。因为内联函数不能在运行中动态确定其位置。 构造函数不能声明为虚函数。多态是指不同的对象对同一消息有不同的行为特性。虚函数作为运行过程中多态的基础,主要是针对对象的,而构造函数是在对象产生之前运行的,因此,虚构造函数是没有意义的。,析构函数可以声明为虚函数。析构函数的功能是在该类对象消亡之前进行一些必要的清理工作。析构函数没有类型,也没有参数,和普通成员函数相比,虚析构函数情况略为简单些。,虚析构函数的声明语法如下: virtual类名 例如: classB public: / virtualB(); ;,8.4 抽象类,8.4.1 纯虚函数 一个抽象类至少带有一个纯虚函数。纯虚函数是一个在基类中说明的虚函数,它在该基类中没有定义具体的操作内容,要求各派生类根据实际需要定义自己的实现内容。纯虚函数的声明形式如下: virtual(参数表)=0 纯虚函数与一般虚函数在书写形式上的不同在于其后面加了“=0”,表明在基类中不用定义该函数,它的实现部分函数体留给派生类去做。,8.4.2 抽象类 抽象类的主要作用是通过它为一个类族建立一个公共的接口,使它们能够更有效地发挥多态特性。使用抽象类时需注意以下几点。 抽象类只能
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 编外人员签订合同管理办法
- 北京 境外 合同法 管辖
- 骨折应急处理
- 山东省枣庄市台儿庄区2024-2025学年七年级上学期期中考试历史试题
- 校园危化品安全教育
- 《丝绸眼罩》规范
- 安徽省亳州市涡阳县高炉学区中心学校2024-2025学年九年级上学期第一次月考历史试卷(含答案)
- 舰船用高压压缩机相关项目投资计划书范本
- 冰雪运动相关行业投资规划报告范本
- 艺术涂料相关行业投资方案范本
- 人教版八年级英语下册各单元知识点汇总
- 美国文化价值观念课件
- 体育科学研究方法-第四章第四节实验法
- 一起电动自行车火灾事故原因认定和分析
- 广东省广州市2023-2024学年高一上学期1月期末英语英语试题(解析版)
- 【教材】第四讲电影案例景别分析
- 家长会课件语文老师
- 2023~2024学年度上期高中2023级期末联考政治双向细目表
- 智慧校园音视频系统整体解决方案
- 视觉传达专业大学规划书
- 22秋可编程控制器应用实训形考任务1-6答案
评论
0/150
提交评论