面向对象程序设计ppt课件

上传人:ni****g 文档编号:568265631 上传时间:2024-07-23 格式:PPT 页数:62 大小:111.50KB
返回 下载 相关 举报
面向对象程序设计ppt课件_第1页
第1页 / 共62页
面向对象程序设计ppt课件_第2页
第2页 / 共62页
面向对象程序设计ppt课件_第3页
第3页 / 共62页
面向对象程序设计ppt课件_第4页
第4页 / 共62页
面向对象程序设计ppt课件_第5页
第5页 / 共62页
点击查看更多>>
资源描述

《面向对象程序设计ppt课件》由会员分享,可在线阅读,更多相关《面向对象程序设计ppt课件(62页珍藏版)》请在金锄头文库上搜索。

1、 第第5 5章章 多态与笼统类多态与笼统类 内容提要内容提要n5.1 5.1 类层次的多态问题类层次的多态问题n5.2 5.2 类型兼容规那么类型兼容规那么( (重点重点) )n5.3 5.3 多态的概念多态的概念n5.4 5.4 多态的分类多态的分类n5.5 5.5 联编联编n5.6 5.6 虚函数虚函数( (重点重点) )n5.7 5.7 笼统类与纯虚函数笼统类与纯虚函数( (重点重点) )提出问题提出问题n【例【例5-15-1】在例】在例4-14-1程序中存在的两个程序中存在的两个缺乏:缺乏:n1 1基类基类Pay()Pay()和和Display()Display()的函数体的函数体均为

2、空,在实现部分仍要写出函数体,均为空,在实现部分仍要写出函数体,显得冗余。显得冗余。n2 2在主函数中,建立了在主函数中,建立了4 4个不同类个不同类的对象,进展了类似的操作,反复写的对象,进展了类似的操作,反复写了了4 4遍类似的语句,程序不够简约。遍类似的语句,程序不够简约。分析问题分析问题n基类设置成员函数基类设置成员函数Pay()Pay()和和Display()Display()的目的是为了一致规定类簇的根本行的目的是为了一致规定类簇的根本行为,虽有冗余,但也必要。为此,为,虽有冗余,但也必要。为此,C+C+提供了纯虚函数来处理此问题。提供了纯虚函数来处理此问题。 n在主函数中建立了在

3、主函数中建立了4 4个不同类的对象,进展个不同类的对象,进展了类似的操作,反复写了了类似的操作,反复写了4 4遍类似的语句。遍类似的语句。n应该怎样有效地来处置它们同样的行为呢应该怎样有效地来处置它们同样的行为呢?我们首先想到的是用循环处理,但调用?我们首先想到的是用循环处理,但调用这些同名函数的对象却不一样。这些同名函数的对象却不一样。n分析这些对象有一个共同点,那就是来自分析这些对象有一个共同点,那就是来自于同一个基类,而基类与派生类对象有什于同一个基类,而基类与派生类对象有什么关系呢?现实上,它们遵照类型兼容规么关系呢?现实上,它们遵照类型兼容规那么。那么。Employee *emp4=

4、&m1,&t1,&s1,&sm1; /Employee *emp4=&m1,&t1,&s1,&sm1; /声明声明笼统类指针数组笼统类指针数组for(int i=0;i4;i+)for(int i=0;iPay(); /empi-Pay(); /单一指令,实现多态,单一指令,实现多态,计算指针指向对象的工资计算指针指向对象的工资empi-Display();/empi-Display();/单一指令,实现多态,单一指令,实现多态,输出指针指向对象的信息输出指针指向对象的信息 5.25.2类型兼容规那么类型兼容规那么n类型兼容规那么是指在需求基类对象类型兼容规那么是指在需求基类对象的任何地方,都

5、可以运用公有派生类的任何地方,都可以运用公有派生类的对象来替代。的对象来替代。n经过公有承继,派生类得到了基类中经过公有承继,派生类得到了基类中除构造函数、析构函数之外的一切成除构造函数、析构函数之外的一切成员。这样,公有派生类实践就具备了员。这样,公有派生类实践就具备了基类的一切功能,凡是基类能处理的基类的一切功能,凡是基类能处理的问题,公有派生类都可以处理。问题,公有派生类都可以处理。 n类型兼容规那么中所指替代包括以下类型兼容规那么中所指替代包括以下情况:情况:n1 1派生类的对象可以赋值给基类的派生类的对象可以赋值给基类的对象。对象。n2 2派生类的对象可以初始化基类的派生类的对象可以

6、初始化基类的援用。援用。n3 3派生类的对象的地址可以赋值给派生类的对象的地址可以赋值给基类的指针变量。基类的指针变量。n在替代之后,派生类对象就可以作为在替代之后,派生类对象就可以作为基类的对象运用,但只能访问从基类基类的对象运用,但只能访问从基类承继的成员。承继的成员。n【例【例5-35-3】例如类型兼容规那么的运用。】例如类型兼容规那么的运用。n教材教材P261P261,该程序的运转结果为:,该程序的运转结果为:nBase classBase classnBase classBase classnBase classBase classnDerivel classDerivel clas

7、snDerive2 class Derive2 class n根据类型兼容规那么,基类指针根据类型兼容规那么,基类指针p p可以可以指向派生类对象指向派生类对象obj2obj2、obj3obj3即派生即派生类对象可以替代基类对象,给基类指类对象可以替代基类对象,给基类指针赋值,但编译时,编译器根据针赋值,但编译时,编译器根据p p的的类型是基类型,自动调用基类的类型是基类型,自动调用基类的who()who(),所以结果如上所示。,所以结果如上所示。 n【思索题【思索题5-35-3】假设基类指针要访问派】假设基类指针要访问派生类的生类的who()who(),怎样办?,怎样办?n nC+C+提供了

8、多态机制来处理这个问题。提供了多态机制来处理这个问题。n类型兼容规那么是类型兼容规那么是C+C+多态的重要根底。多态的重要根底。 多态多态n多态多态PolymorphismPolymorphism是指具有类似是指具有类似功能的不同函数运用同一个称号来实功能的不同函数运用同一个称号来实现,从而可以运用一样的调用方式来现,从而可以运用一样的调用方式来调用这些具有不同功能的同名函数的调用这些具有不同功能的同名函数的特性。特性。 5.4 5.4 多态的分类多态的分类nC+C+支持的多态可以分为四种类型:支持的多态可以分为四种类型:n重载多态:函数重载和运算符重载重载多态:函数重载和运算符重载n强迫多态

9、:强迫类型转换强迫多态:强迫类型转换n包含多态:虚函数包含多态:虚函数n参数多态:函数模板和类模板参数多态:函数模板和类模板 联编联编n联编是指把一个标识符名和一个存储联编是指把一个标识符名和一个存储地址联络在一同的过程。即函数调用地址联络在一同的过程。即函数调用与某个函数在多态的实现过程中,确与某个函数在多态的实现过程中,确定调用哪个同名联络的过程,又称绑定调用哪个同名联络的过程,又称绑定。分为:定。分为:n静态联编静态联编n动态联编动态联编n静态联编是在编译阶段完成的联编。静态联编是在编译阶段完成的联编。例例5-25-2、例、例5-35-3及以前的函数重载都是及以前的函数重载都是采用静态联

10、编方式。采用静态联编方式。n例例5-45-4,教材,教材P265P265,是静态联编。,是静态联编。n动态联编是在运转阶段完成的联编。动态联编是在运转阶段完成的联编。 n在例在例5-45-4中,静态联编把基类指针中,静态联编把基类指针psps指指向的对象绑定到基类上,而在运转时向的对象绑定到基类上,而在运转时进展动态联编将把进展动态联编将把psps指向的对象绑定指向的对象绑定到派生类上。到派生类上。n可见,同一个指针,在不同阶段被绑可见,同一个指针,在不同阶段被绑定的类对象将是不同的,进而被关联定的类对象将是不同的,进而被关联的类成员函数也是不同的。的类成员函数也是不同的。n如何来确定是用静态

11、联编还是用动态如何来确定是用静态联编还是用动态联编呢?联编呢?nC+C+规定,动态联编经过承继和虚函数规定,动态联编经过承继和虚函数来实现。来实现。n虚函数是动态联编的根底。下面引见虚函数是动态联编的根底。下面引见虚函数。虚函数。5.6 5.6 虚函数虚函数n虚函数就是在基类中被关键字虚函数就是在基类中被关键字virtualvirtual阐明、并在一个或多个派生类中被重阐明、并在一个或多个派生类中被重新定义的成员函数。新定义的成员函数。n声明虚函数的格式如下:声明虚函数的格式如下:nvirtual virtual (););n在派生类中重新定义虚函数时,其函在派生类中重新定义虚函数时,其函数原

12、型包括前往类型、函数名、参数数原型包括前往类型、函数名、参数个数与参数类型的顺序,都必需与基个数与参数类型的顺序,都必需与基类中的原型必需一样。类中的原型必需一样。n一个函数一旦被声明为虚函数,那么一个函数一旦被声明为虚函数,那么无论声明它的类被承继了多少层,在无论声明它的类被承继了多少层,在每一层派生类中该函数都坚持虚函数每一层派生类中该函数都坚持虚函数特性。因此,在派生类中重新定义该特性。因此,在派生类中重新定义该函数时,可以省略关键字函数时,可以省略关键字virtualvirtual。但。但是,为了提高程序的可读性,往往不是,为了提高程序的可读性,往往不省略。省略。n在程序运转时,不同类

13、的对象调用各在程序运转时,不同类的对象调用各自的虚函数,这就是运转时多态。自的虚函数,这就是运转时多态。n【例【例5-55-5】将例】将例5-45-4基类的成员函数基类的成员函数printprint()()设为虚函数,采用对象指针调用虚设为虚函数,采用对象指针调用虚函数,进而实现动态联编。函数,进而实现动态联编。 n该程序的运转结果为该程序的运转结果为: :nA studentA studentnA graduate studentA graduate studentnA studentA studentnA studentA studentnA graduate studentA gradu

14、ate studentn【思索题【思索题5-55-5】假设将例】假设将例5-55-5中中StudentStudent类改类改为:为:nclass Studentclass Studentn npublic:public:n virtual void print(); virtual void print(); /虚函数虚函数的声明的声明n;nvirtual void Student:print() /virtual void Student:print() /虚函虚函数的实现数的实现n n coutA studentendl; coutA studentendl;n n留意:当有虚函数声明时,

15、留意:当有虚函数声明时,virtualvirtual关关键字只用在虚函数的声明中,不能用键字只用在虚函数的声明中,不能用在虚函数定义中。在虚函数定义中。 n【思索题【思索题5-45-4】将例】将例5-55-5中用对象调用中用对象调用虚函数,其结果如何?虚函数,其结果如何?n【留意】只需经过对象指针或对象援【留意】只需经过对象指针或对象援用来调用虚函数,才干实现动态联编。用来调用虚函数,才干实现动态联编。假设采用对象来调用虚函数,那么采假设采用对象来调用虚函数,那么采用的是静态联编方式。用的是静态联编方式。n【例【例5-65-6】将例】将例5-45-4基类的成员函数基类的成员函数printpri

16、nt()()设为虚函数,采用对象援用调用虚设为虚函数,采用对象援用调用虚函数,进而实现动态联编。函数,进而实现动态联编。 n运转结果阐明,只需定义一个基类的运转结果阐明,只需定义一个基类的对象指针或对象援用,就可以调用期对象指针或对象援用,就可以调用期望的虚函数。望的虚函数。n思索题思索题: :假设将对象援用或对象指针换假设将对象援用或对象指针换为对象为对象, ,那么是静态联编。那么是静态联编。n在实践运用中,编程人员不用过多地在实践运用中,编程人员不用过多地思索类的层次关系,无须显式地写出思索类的层次关系,无须显式地写出虚函数的途径,只须将对象指针指向虚函数的途径,只须将对象指针指向相应的派

17、生类或援用相应的对象,经相应的派生类或援用相应的对象,经过动态联编就可以对音讯做出正确的过动态联编就可以对音讯做出正确的反响。反响。小结小结1 1假设他期望在派生类中重新定义一假设他期望在派生类中重新定义一个成员函数,那么他就应该在基类中个成员函数,那么他就应该在基类中把该函数设为把该函数设为virtualvirtual。2 2以单一指令调用不同函数,这种性以单一指令调用不同函数,这种性质就是质就是 多态多态 。3 3虚函数是虚函数是C+C+言语的多态性质和动言语的多态性质和动态绑定的关键。态绑定的关键。4 4虚函数派生下去仍是虚函数,而且虚函数派生下去仍是虚函数,而且可以省略可以省略virt

18、ualvirtual关键词。关键词。n【思索题【思索题5-85-8】虚函数与虚拟承继有什】虚函数与虚拟承继有什么类似的地方?他们之间有没有联络么类似的地方?他们之间有没有联络?n假设能了解假设能了解C+C+编译器对于虚函数的实编译器对于虚函数的实现方式,我们就能知道为什么虚函数现方式,我们就能知道为什么虚函数可以实现动态绑定。下面引见虚函数可以实现动态绑定。下面引见虚函数表。表。5.6.3 5.6.3 虚函数表虚函数表n为了到达了到达动态绑定的目的,定的目的,C+C+编译器器经过某个表格,在某个表格,在执行期行期间“间接接调用用实践上欲践上欲绑定的函数,定的函数,这样的表格的表格称称为虚函数表

19、虚函数表vtablevtable。n每一个含有虚函数的类,编译器都为每一个含有虚函数的类,编译器都为它做一个虚函数表,表中的每一项都它做一个虚函数表,表中的每一项都指向一个虚函数的地址,实现上是一指向一个虚函数的地址,实现上是一个函数指针的数组。此外,编译器也个函数指针的数组。此外,编译器也会为类加上一个数据成员,是一个指会为类加上一个数据成员,是一个指向该虚函数表的指针向该虚函数表的指针vptrvptr。 Wind objectWind objectvptrvptrStringed objectStringed objectvptrvptrPercussion objectPercussio

20、n objectvptrvptr&Wind:play()&Wind:play()& Percussion:play& Percussion:play()()& Stringed:play()& Stringed:play()n当经过对象调用虚函数时,是经过当经过对象调用虚函数时,是经过vptrvptr找到虚函数表,再找出虚函数的找到虚函数表,再找出虚函数的真正地址。真正地址。n至于基类指针或援用指向派生类对象至于基类指针或援用指向派生类对象时,调用的是派生类虚函数,其微妙时,调用的是派生类虚函数,其微妙在于虚函数表以及一种间接调用方式:在于虚函数表以及一种间接调用方式:n虚函数表中的内容根据类

21、中的虚函数虚函数表中的内容根据类中的虚函数声明次序,一一填入函数指针。声明次序,一一填入函数指针。n派生类会承继基类的虚函数表以及派生类会承继基类的虚函数表以及其它一切可以承继的成员,我们在其它一切可以承继的成员,我们在派生类中改写虚函数时,虚函数表也派生类中改写虚函数时,虚函数表也遭到了影响,表中每一项所指向函数遭到了影响,表中每一项所指向函数地址将不再是基类中的函数地址,而地址将不再是基类中的函数地址,而是派生类的函数地址。是派生类的函数地址。n因此,一个指向因此,一个指向StudentStudent对象的指针,对象的指针,所调用的所调用的printprint函数就是函数就是Student

22、:print(), Student:print(), 而一个指向而一个指向GStudentGStudent对象的指针,所调用的对象的指针,所调用的printprint函数就是函数就是GStudent:print()GStudent:print()。 n将一个类的成员函数定义为虚函数有将一个类的成员函数定义为虚函数有利于编程,虽然它会引起一些额外的利于编程,虽然它会引起一些额外的开销。开销。n那么,能否一切成员函数都可以声明那么,能否一切成员函数都可以声明为虚函数呢?为虚函数呢?n普通来说,可将类簇中具有共性的成普通来说,可将类簇中具有共性的成员函数声明为虚函数,而具有个性的员函数声明为虚函数,

23、而具有个性的函数没有必要声明为虚函数。但是下函数没有必要声明为虚函数。但是下面的情况例外:面的情况例外:n(1)(1)静态成员函数不能声明为虚函数。由于静态成员函数不能声明为虚函数。由于静态成员函数不属于某一个对象,没有多静态成员函数不属于某一个对象,没有多态性的特征。态性的特征。n(2)(2)构造函数不能是虚函数。构造函数是在构造函数不能是虚函数。构造函数是在定义对象时被调用,完成对象的初始化,定义对象时被调用,完成对象的初始化,此时对象还没有完全建立。虚函数作为运此时对象还没有完全建立。虚函数作为运转时的多态性的根底,主要是针对对象的,转时的多态性的根底,主要是针对对象的,而构造函数是在对

24、象产生之前运转的。所而构造函数是在对象产生之前运转的。所以,将构造函数声明为虚函数是没有意义以,将构造函数声明为虚函数是没有意义的。的。 n(3)(3)内联成员函数不能声明为虚函数。内联成员函数不能声明为虚函数。由于内联函数的执行代码是明确的,由于内联函数的执行代码是明确的,在编译时已被交换,没有多态性的特在编译时已被交换,没有多态性的特征。假设将那些在类声明时就定义内征。假设将那些在类声明时就定义内容的成员函数声明为虚函数,此时函容的成员函数声明为虚函数,此时函数不是内联函数,而以多态性出现。数不是内联函数,而以多态性出现。n(4)(4)析构函数可以是虚函数,且往往被析构函数可以是虚函数,且

25、往往被定义为虚函数。普通来说,假设某类定义为虚函数。普通来说,假设某类中有虚函数,那么其析构函数也该当中有虚函数,那么其析构函数也该当定义为虚函数。定义为虚函数。n特别是需求析构函数完成一些有意义特别是需求析构函数完成一些有意义的操作,如释放内存时,由于实施多的操作,如释放内存时,由于实施多态性时是经过将基类的指针指向派生态性时是经过将基类的指针指向派生类的对象来完成的,假设删除该指针,类的对象来完成的,假设删除该指针,就会调用该指针指向的派生类的析构就会调用该指针指向的派生类的析构函数,而派生类的析构函数又自动调函数,而派生类的析构函数又自动调用基类的析构函数,这样整个派生类用基类的析构函数

26、,这样整个派生类的对象才被完全释放。的对象才被完全释放。n因此,析构函数常被声明为虚函数。因此,析构函数常被声明为虚函数。假设一个类的析构函数是虚函数,那假设一个类的析构函数是虚函数,那么,由它派生的一切子类的析构函数么,由它派生的一切子类的析构函数也是虚函数。也是虚函数。n下面引见虚析构函数。下面引见虚析构函数。5.6.4 5.6.4 虚析构函数虚析构函数n虚析构函数的声明格式如下:虚析构函数的声明格式如下:nvirtual virtual ();();n【例【例5-75-7】虚析构函数例如。教材】虚析构函数例如。教材P272P272n利用虚函数可以使所设计的软件系统利用虚函数可以使所设计的

27、软件系统变得灵敏,提高了代码的可重用性。变得灵敏,提高了代码的可重用性。n虚函数为一个类簇中一切派生类的同虚函数为一个类簇中一切派生类的同一行为提供了一致的接口,使得程序一行为提供了一致的接口,使得程序员在运用一个类簇时只须记住一个接员在运用一个类簇时只须记住一个接口即可。口即可。本卷须知本卷须知n(1)(1)假设在派生类中没有重新定义虚函假设在派生类中没有重新定义虚函数,那么派生类的对象将运用基类的数,那么派生类的对象将运用基类的虚函数代码。虚函数代码。n(2)(2)在派生类中重新定义虚函数时,必在派生类中重新定义虚函数时,必需保证函数值类型和参数与基类中的需保证函数值类型和参数与基类中的声

28、明完全一致。否那么,派生类的函声明完全一致。否那么,派生类的函数也不具备多态性。数也不具备多态性。n根据上述引见,我们可以将例根据上述引见,我们可以将例5-15-1的的PayPay()()和和Display()Display()定义为虚函数,从而处定义为虚函数,从而处理例理例4-14-1遗留下来的第二个问题。遗留下来的第二个问题。n另外,公司的人员有另外,公司的人员有4 4类,它们的基类类,它们的基类EmployeeEmployee实践上是不需求实例化对象实践上是不需求实例化对象的,的,EmployeeEmployee也无法为虚函数定义详也无法为虚函数定义详细的实现,这时可以将细的实现,这时可

29、以将EmployeeEmployee声明声明为纯虚函数。包含纯虚函数的类称为为纯虚函数。包含纯虚函数的类称为笼统类。笼统类。5.7 5.7 笼统类和纯虚函数笼统类和纯虚函数n笼统类专门作为基类派生新类。笼统笼统类专门作为基类派生新类。笼统类的主要作用是将有关的派生类组织类的主要作用是将有关的派生类组织在一个承继层次构造中,由笼统类为在一个承继层次构造中,由笼统类为它们提供一个公共的根,相关的派生它们提供一个公共的根,相关的派生类就从这个根派生出来。类就从这个根派生出来。 n含有纯虚函数的类就是笼统类。含有纯虚函数的类就是笼统类。 n在例在例4-14-1中遗留的另一个问题是中遗留的另一个问题是:

30、 : employeeemployee类的成员函数类的成员函数pay()pay()和和displaydisplay()()的函数体为空的函数体为空, ,在实现部分仍要写出在实现部分仍要写出函数体函数体, ,显得冗余。显得冗余。n现实上,现实上,employeeemployee类的成员函数根本类的成员函数根本不会被调用,所以不用定义它。于是不会被调用,所以不用定义它。于是+提供了纯虚函数来处理这个问题。提供了纯虚函数来处理这个问题。 纯虚函数纯虚函数n纯虚函数是为理处理在基类中无法实纯虚函数是为理处理在基类中无法实现的函数现的函数, ,而在派生类中再给出函数的而在派生类中再给出函数的详细实现,它

31、只需求在基类中阐明函详细实现,它只需求在基类中阐明函数原型用来规定整个类簇的一致接口数原型用来规定整个类簇的一致接口方式。方式。n纯虚函数的声明格式为:纯虚函数的声明格式为:nvirtual virtual ()=0;)=0;n纯虚函数与函数体为空的虚函数是有纯虚函数与函数体为空的虚函数是有区别的:区别的:n前者有函数体前者有函数体, ,而后者没有函数体;而后者没有函数体;n前者所在的类是笼统类前者所在的类是笼统类, ,不能直接进展不能直接进展实例化实例化, ,而后者所在的类是可以实例化而后者所在的类是可以实例化的。的。 n【例【例5-95-9】例如纯虚函数及笼统类。计】例如纯虚函数及笼统类。

32、计算图形面积。例如,要定义一个算图形面积。例如,要定义一个SquareSquare类和类和CircleCircle类,它们有共同的类,它们有共同的属性属性x x、y y,以及共同的操作,以及共同的操作setvaluesetvalue()()和和area()area(),由于,由于area()area()在两个类的在两个类的计算方法不同,但又属于一个类簇,计算方法不同,但又属于一个类簇,为此,定义一个笼统类为此,定义一个笼统类ShapeShape,一致它,一致它们的属性和操作。笼统类和纯虚函数们的属性和操作。笼统类和纯虚函数的的UMLUML图表示如图图表示如图5-35-3所示。所示。ShapeS

33、hape# x:int# x:int# y:int# y:int+ setvalue():void+ setvalue():void+area():void+area():voidSquareSquare+ area():void+ area():voidCircleCircle+ area():void+ area():voidn至此,我们可以用至此,我们可以用C+C+提供的多态性来提供的多态性来处理本章开头提出的问题。处理本章开头提出的问题。n例例5-15-1,教材,教材P280P280EmployeeEmployee#name:char10#name:char10#no:int#no:i

34、nt#salary:float#salary:float#maxno:int=1000#maxno:int=1000+Employee ()+Employee ()+Pay():void+Pay():void+Display():void+Display():voidTechnicianTechnician-hourlyrate:float-hourlyrate:float-worknours:int-worknours:int+Technician()+Technician()+Pay():void+Pay():void+Display():void+Display():voidSalesm

35、anSalesman#commrate:float#commrate:float#sales: float#sales: float+Salesman()+Salesman()+Pay():void+Pay():void+Display():void+Display():voidManagerManager+Manager()+Manager()+Pay():void+Pay():void+Display():void+Display():void#monthlypay: float#monthlypay: float+SalesManager()+SalesManager()+Pay():void+Pay():void+Display():void+Display():voidSalesManagerSalesManager 本章小结本章小结n5.1 5.1 类层次的多态问题类层次的多态问题n5.2 5.2 类型兼容规那么类型兼容规那么( (重点重点) )n5.3 5.3 多态的概念多态的概念n5.4 5.4 多态的分类多态的分类n5.5 5.5 联编联编n5.6 5.6 虚函数虚函数( (重点重点) )n5.7 5.7 笼统类与纯虚函数笼统类与纯虚函数( (重点重点) )

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 建筑/环境 > 施工组织

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号