设计模式学习及其C语言实现笔记

上传人:仙*** 文档编号:122736862 上传时间:2022-07-21 格式:DOC 页数:11 大小:246KB
收藏 版权申诉 举报 下载
设计模式学习及其C语言实现笔记_第1页
第1页 / 共11页
设计模式学习及其C语言实现笔记_第2页
第2页 / 共11页
设计模式学习及其C语言实现笔记_第3页
第3页 / 共11页
资源描述:

《设计模式学习及其C语言实现笔记》由会员分享,可在线阅读,更多相关《设计模式学习及其C语言实现笔记(11页珍藏版)》请在装配图网上搜索。

1、【精品文档】如有侵权,请联系网站删除,仅供学习与交流设计模式学习及其C语言实现笔记.精品文档.设计模式学习及其C语言实现笔记第1章:面向对象C语言(Object Oriented C)我曾经在嵌入式控制系统工作过,苦于嵌入式系统编程一直是C语言,而没法用C+或其他高级语言的面向对象方法编程。每次做项目,代码基本上都是重头再来,以前的代码有少量的可以copy过来直接用,开发和维护很不方便。偶然间发现UML+OOPC嵌入式C语言开发精讲里面详细的讲述了OOC的原理和实现方法,感觉不错。遗憾的是上面只提供接口和多态的实现方法,没有提供继承的处理。根据本人的研究,将其上面的宏文件进行修改和扩充,提出一

2、种可行而且结构明了的继承实现方法。至此,C的OO编程中的封装、继承、多态都全实现了。面向对象C语言(Object Oriented C)只是运用单纯的C的宏(Macro)技巧,实现面向对象的基本技术。借用OOC.H 文件的宏,就可以实现类的封装、继承、多态。OOC毕竟不是一门语言,不可能做出与C+或C#这些面向对象语言一样的干练、简洁,有的甚至没法实现比如对private成员变量的限制等。但OOC方法借用宏在一定的规则下还是能做出比较漂亮的面向对象代码。下面是对比C+介绍OOC.H文件中的对象的命名、定义、封装等的规则。1、类的封装和对象的构造1.1类的封装(类的定义)在C+中,类的定义如下c

3、lass myClassprivate:int a; /-类属性(变量)public: myClass(); void Set(int a); void put();在OOC中“类”实际是结构体,myClass 定义的风格为CLASS(myClass)int a; /-类属性(变量)void (*init)(void *t); /-初始化成员变量用函数void (*Set)(void *t,int a); /-函数指针void (*Put)(void *t); 在C+和OOC的类封装中,最大的区别是OOC用函数指针来表示类的方法(或成员函数);此外OOC中没有private的变量,privat

4、e变量只能通过定义方法来实现,比如把int a 改写为int _a,这样也许外面误访问的可能性大大降低,但还是不能阻止外面访问。1.2类的成员函数的实现C+中可以在类内部定义成员函数的实现,也可以在类的外面。而OOC中的类实质是struct,其所存放的只能是变量,其中的函数指针变量是用来实现类的方法。因此在OOC的类中是不能定义函数的实现的。OOC中函数也不像C+中的函数属于哪个类就和哪个类紧密结合在一起。OOC中的函数的实现就是普通的函数实现,只是函数的参数要和CLASS()宏定义的函数(指针)的参数变量保持一致。例如myClass类的Set方法可以取名Set,也可以用别的名。如果在一个.C

5、文件中,成员函数取名模式为: funName_ClassName(),这样比较便于阅读和区分。按照该规则,则myClass的方法实现定义如下:void init_myClass(void *t)myClass *cthis = t;cthis-a = init_Number; /赋你想要赋给的初始值,也可以通过增加init()参数传进来void Set_myClass(void*t,int a)myClass *cthis = t;cthis-a = a;void Put _myClass(void*t)myClass *cthis = t;printf(“n this is myClass

6、fun”);这里和C+不同的是,在C+中,成员函数可以直接访问类的成员变量,而OOC中的成员函数要访问成员变量,必须要有参数传递过来,因此,OOC中凡是要访问其成员变量的必须要增加一个void*t 的参数。比如函数Set()在C+只要有一个int参数就行了,在OOC中必须要带有一个void*指针参数,通过该参数才能访问到myClass类的其他变量或者成员函数。1.3对象的构造在C+中,定义了一个对象的同时也调用了构造函数。在OOC中没有这样的功能,OOC的对象定义,实际上只是定义了个含有函数指针的结构体,要使得该结构体变成相当于C+中的对象,必须要对该对象 (结构体)的成员变量进行初始化和方法

7、(指针函数)与具体定义的函数进行关联。在C+中这两步一下就在定义对象时候自动调用构造函数现了,而OOC中只能分两步走。因此,在myClass定义中,C+没有 void init(void *t) 函数,而任何OOC定义的类必须要包含该函数(指针,接口和抽象类除外),否则无法对成员变量进行初始化。根据OOC中的宏,以myClass为例,对象的构造函数格式如下:CTOR(myClass)FUNCTION_SETTING(init, init_myClass); FUNCTION_SETTING(Set, Set_myClass);FUNCTION_SETTING(Put, Put_myClass)

8、;END_CTOR构造函数把对象中的函数指针和函数关联起来,调用函数指针就是对函数的调用。通过该构造函数后,OOC定义的对象才是一个真正意义上的对象,即函数指针有了函数的功能。1.4、对象的实例化和规则定义好类后就要实例化,在C+中,myClass的对象定义为:myClass myObject;其中已经隐含了myObject对象的构造和成员变量的初始化。 在OOC中,其定义和处理3步如下:myClass myObject; / 1、定义对象CLASS_CTOR(myClass,myObject); / 2、构造对象使得函数指针和函数关联myObject.init(&myObject); / 3

9、、初始化对象的成员变量,注意:& myObject(取地址)至此,当个类的定义、封装、对象的构造和初始化就结束了。2、继承和接口的实现2.1、继承和C实现在C+继承就是子类不需要重新定义拥有了其父类的public 和protect 的成员变量和成员函数。如果子类中重新定义了父类的方法,如果父类该方法是虚函数,则子类函数覆盖了父类函数;如果父类函数不是虚函数则为子类函数隐藏了父类函数。覆盖和隐藏的区别是:如果发生覆盖,当父类指针指向子类对象时,通过指针调用同名虚函数,则执行子类的虚函数;如果发生隐藏,则调用的是父类的同名函数。例如:class BaseApublic: BaseA() Virtu

10、al void Put()cout “ 调用BaseA的函数”endl;class BaseBpublic: BaseB() void Put()cout “ 调用BaseB的函数” endl;class ChildA : public BaseApublic: ChildA () void Put()cout “ 调用ChildA的函数” endl;class ChildB : public BaseBpublic: ChildB () void Put()cout “ 调用ChildB的函数” Put(); /- 调用子类ChildA的Put()函数; BaseB *pb = new Ch

11、ildB(); pb-Put(); /- 调用父类BaseB的Put()函数;输出结果是:调用ChildA的函数调用BaseB的函数在OOC 中只是借用C 的宏没法实现C+这些复杂的机制,但能实现基本的继承,即拥有父类的全部属性和方法。OOC中没有私有、保护属性的概念,所有父类属性和方法都是可见的。通过构造函数的处理,可以在OOC中实现隐藏和覆盖。下面是OOC中的隐藏和覆盖的讲解,在设计模式中更多的是覆盖,而隐藏用到的比较少。2.2、继承中覆盖和隐藏的实现为了方便解说,用myClass做基类,则定义子类myChildA的方法如下CLASS(myChildA) /-本书OOC目前只研究单继承EX

12、TENDS(myClass); /-表示继承myClass类,必须放在最前面 int data;void (*init)(void *t);void (*Put)(void*t);子类要注意的地方有3点:1、 被继承的类的宏说明EXTENDS(baseClass) 必须放在子类定义的最开头。2、 子类的init()函数里面必须要调用基类的init()函数,否则基类的属性没有初始化。3、 在构造子类的地方CTOR(myChildA)下最开头必须要增加调用基类构造的宏。myChildA 类的初始化函数定义如下:void init_ myChildA(void *t)myChildA *cthis

13、= t;cthis- myClass.init(&cthis- myClass); /-基类的初始化, 注意:&cthis- myClass/-与基类的init()函数参数要一致cthis-data = yourNumber; myChildA虚函数覆盖的实现假定myClass类中Put()为虚函数,则子类必须定义自己Put()的实现,myChildA自己重新定义的Put()如下:void Put_ myChildA ()printf(“this is myChildA fun、n”);于是在构造函数中,遵循C+的原理,先对基类进行构造,然后对基类的虚函数重新绑定,具体处理代码如下CTOR(m

14、yChildA)BASE_CTOR(myClass); /-调用基类构造函数实现对基类函数关联FUNCTION_SETTING(myClass.Put, Put_ myChildA); / -Put()的虚函数实现关联绑定FUNCTION_SETTING(init, init_ myChildA); FUNCTION_SETTING(Put, init_ myChildA);END_CTOR在CTOR(myChildA)中,通过重新设置子类内的myChildA .Put的关联函数,从而实现虚函数的意义。如果要实现C+中的隐藏功能,只要将 FUNCTION_SETTING(myChildA .P

15、ut, Put_ myChildA)去掉就是了,因为BASE_CTOR(myClass)已经将myClass.Put与Put_ myClass 关联了。实现隐藏的构造函数如下:CTOR(myChildA)BASE_CTOR(myClass); /-调用基类构造函数实现对基类函数关联FUNCTION_SETTING(init, init_ myChildA); FUNCTION_SETTING(Put, init_ myChildA);END_CTOR继承中的覆盖和隐藏中,都共同的调用宏BASE_CTOR(baseClass),调用该宏的前提条件是baseClass不是抽象类,baseClass

16、必须有自己的 CTOR(baseClass), 否则编译可能正确但连接运行一定错误。2.3、接口和抽象类及其多态的实现接口是Java 和C#提出的概念,在C+中抽象类可以当作接口处理。同样,OOC中定义的接口和抽象类的差别的是:接口没有数据成员变量,接口没有自己的构造函数;抽象类可以有数据成员变量。本书OOC中的接口就是没有数据成员的抽象类。抽象类如果带有数据成员则必须有初始化成员函数和构造函数。下面结合一个简单运算器的实例说明OOC中的接口和多态的实现。简单的运算器有加法、减法、乘法、除法的功能。多态就是用相同的语句结构表达不同的功能。采用多态处理计算器的目的,就是客户调用端运算的代码是一致

17、的,只需要少量的变化就能实现不同的功能。基于这样的分析,首先要抽象一个类或者接口,它负责不同情况下的计算,所以它没有具体的代码。具体的实现代码由其子类来实现,于是OOC里定义该接口为:INTERFACE(IOperation)double GetResult(double numA, double numB);这就是OOC中定义接口的方法。本例中的接口只有一个函数,根据需要可以增加。接下来巴加法、减法、乘法、除法分别定义成IOperation接口的实现(也可以说是子类)。/-加法类CLASS(COperationAdd)IMPLEMENTS(IOperation);/-减法类CLASS(COp

18、erationSub)IMPLEMENTS(IOperation);乘法类、和除法类与此类同,在此省略。OOC中用IMPLEMENTS()宏主要是为了更加接近Java的表达,实际上用 EXTENDS() 也是一样,定义含义完全相同的两个宏主要是方便理解。对于接口的实现(或者说继承接口的子类),它的构造和继承有点不同,最大的不同是在CTOR()下面不需要调用父类构造函数的宏BASE_CTOR()。接口方法的关联与继承中的虚函数的关联比较类似。下面是COperationAdd类的构造函数:CTOR(COperationAdd)FUNCTION_SETTING (IOperation.GetResu

19、lt, GetResult_COperationAdd); /-接口函数的实现关联END_CTOR减法类的构造函数:CTOR(COperationSub)FUNCTION_SETTING (IOperation.GetResult, GetResult_COperationSub); /-接口函数设置END_CTOR其他类的关联也是类似,只是关联的实现函数名不同而已。主函数的调用void main() /-定义运算操作对象IOperation *pOper; /-定义接口指针,多态实现用COperationAdd Add;COperationSub Sub;COperationMul Mul;

20、COperationDiv Div;double result=0;/-类的构造CLASS_CTOR(COperationAdd,Add);CLASS_CTOR(COperationSub,Sub);CLASS_CTOR(COperationMul,Mul);CLASS_CTOR(COperationDiv,Div);/-静态内存分配处理方法pOper = &Add;result = pOper-GetResult(53.12,86.4);printf(ADD: 53.12+86.4 =%6.3frn,result);pOper = ⋐ /-减法result = pOper-GetRe

21、sult(53.12,86.4);printf(Sub: 53.12-86.4 =%6.3frn,result);pOper = &Mul; /-乘法result = pOper-GetResult(53.12,86.4);printf(Mul: 53.12*86.4 =%6.3frn,result);pOper = &Div; /-除法result = pOper-GetResult(53.12,86.4);printf(Div: 53.12/86.4 =%6.4frn,result);/-动态内存分配方法-/-加法printf(rn dynamic memory:rnn);pOper =N

22、ew(COperationAdd);result = pOper-GetResult(12.5,36.8);printf(ADD: 12.5+36.8 =%6.3frn,result);/-减法pOper =New(COperationSub);result = pOper-GetResult(12.5,36.8);printf(Sub: 12.5-36.8 =%6.3frn,result);/-乘法pOper =New(COperationMul);result = pOper-GetResult(12.5,36.8);printf(Mul: 12.5*36.8 =%6.3frn,resul

23、t);/-除法pOper =New(COperationDiv);result = pOper-GetResult(12.5,36.8);printf(Div: 12.5/36.8 =%6.3frn,result);结果输出如下:ADD: 53.12+86.4 =139.520Sub: 53.12-86.4 =-33.280Mul: 53.12*86.4 =4589.568Div: 53.12/86.4 =0.6148 dynamic memory:ADD: 12.5+36.8 =49.300Sub: 12.5-36.8 =-24.300Mul: 12.5*36.8 =460.000Div:

24、12.5/36.8 = 0.340从main()函数的调用可以看出,处理运算始终是 pOper-GetResult(numA , numB) 这条语句,改变其运算功能,只需要改变 pOper 所指向的对象。这就是多态,相同的语句实现不同的功能。抽象和多态在面向对象C和设计模式中将显示出强大的威力。第2章:面向对象C 必要基础知识为了帮助大家理解OOC和更好的使用OOC,这章主要是讲解一些必要的C语言和宏定义,介绍OOC.h 为什么要这样设计。1、 本书的OOC书写规则1.1、 普通类的定义CLASS(className) typeName data; void (*init)(void*t,

25、type others); /必须有该函数,参数至少有void*t typeName (*m_function)(void*t, type others); /-至少有void*t 参数,其他看情况普通类是没有继承过任何类、任何接口的类。普通类必须要有1.2、抽象类的定义ABSTRACT_CLASS(className) typeName data; void (*init)(void*t, type others); /必须有该函数,参数至少有void*t typeName (*m_function)(void*t, type others); /-至少有void*t 参数,其他看情况 实质

26、上和普通类是一样的定义,只是没有自己的方法实现,宏ABSTRACT_CLASS目的是帮助程序的可读性。如果抽象类没有数据data,最好就定义为接口。1.3、接口和实现INTERFACE(IName)typeName (*m_function)( type others); /-参数看情况而定,不一定有void*t参数CLASS(Chid_Implement)IMPLEMENTS(IName);void (*init)(void*t); /-其他方法据情况增减接口的出现就是希望一个接口能有多个实现,一个接口至少有一个实现,接口只有在有2个实现以上才有意义,否则接口可以合并到子类中去。1.4 继承

27、:在子类的最开头加宏EXTENDS(baseClass); 例如CLASS(B) EXTENDS(A); /-B继承A,必须放在最开头1.5、 类的构造: 将函数指针和函数关联没有父类的类的构造:CTOR(ClassName)FUNCTION_BINDING(FUN1,FUN2);END_CTOR有继承的类的构造:CTOR(ClassName)BASE_CTOR(baseClass)FUNCTION_BINDING(FUN1,FUN2);END_CTOR1.6、 动态内存分配ClassName *pClass = New_ClassName(); 或者ClassName *pClass = N

28、EW(ClassName); 或ClassName *pClass = New(ClassName);提供多种方法,读者可以根据自己的喜好选择,本人习惯用pClass = New(ClassName),方式,这样New()看起来更接近C+运算符new。1.7、 显式构造函数CLASS_CTOR(ClassName, objName); 或者ClassName_Setting(&objName)这两个宏展开后实际上是一样的,提供两种方法是方便不同人的使用习惯。显式构造函数主要用于类实例化后对其进行构造。在动态内存分配中已经隐含了对该宏对应的函数的调用。1.8、 动态对象内存释放DEL(p);或者

29、DELETE(p);2、面向对象OOC.H 的设计及其关键宏含义面向对象C的关键宏头文件OOC.H最初的设计思想来源于高焕堂老师著的UML+OOPC嵌入式C语言开发精讲中的lw_oopc_kc.h。原作中提供了类的封装和接口,以及在这基础上演化的对象、信息传递和接口多态等。本文在其基础上进行了符合自己编程习惯的改进,并增加了继承机制。从而OOC中实现类的封装、继承和多态,从而实现了OO中的三大主要特征。基于此的基础上还考虑虚函数的处理方法等。OOC.H的文件内容为:/*- ooc.h -*/ #ifndef _OOC_H#define _OOC_H#include 默认可以动态内存分配,如果不

30、使用动态内存分配,在 #include OOC.H 前定义#define OOC_SMALL,或者 #define OOC_STATIC#ifndef OOC_SMALL #ifndef OOC_STATIC #define New(type) New_#type() /dynmic mode #define NEW(type) New_#type() /dynmic mode #define DELETE(type) free(type) / free the memory #define DEL(type) free(type) #endif#endif#define CLASS(type

31、) typedef struct type type; struct type#ifndef OOC_SMALL #ifndef OOC_STATIC #ifndef OOC_DYNAMIC #define CTOR(type) void* type#_Setting(type*); void* New_#type() struct type *cthis; cthis = (struct type *)malloc(sizeof(struct type); return type#_Setting(cthis); void* type#_Setting(type *cthis) #else

32、#define CTOR(type) void* New_#type() struct type *cthis; cthis = (struct type *)malloc(sizeof(struct type); #endif #else #define CTOR(type) void* type#_Setting(type *cthis) #endif#endif#define END_CTOR return (void*)cthis; #define FUNCTION_SET(pfun, fun) cthis-pfun = fun;#define IMPLEMENTS(type) typ

33、e type#define INTERFACE(type) typedef struct type type; struct type/-转义定义-/#define CLASS_CTOR(type,obj) type#_Setting(&obj)#define EXTENDS(BaseClass) IMPLEMENTS(BaseClass)#define BASE_CTOR(type)CLASS_CTOR(type,cthis-type); /CLASS_CTOR(A,cthis-A);#define ABSTRACT_CLASS CLASS#define FUNCTION_SETTING F

34、UNCTION_SET/ Virtual 是一个空格,在这里只是提示用,没有任何意义#define Virtual #endif/*- end -*/2.1、宏CLASS(className)CLASS(className)展开后为:typedef struct className className; struct className也就是说:className 不仅是个结构体名,同时还表示:struct className;因为在C中定义结构体变量时候必须有struct在前,如:struct A用结构体A定义一个结构体变量a,应写为:struct A a;这点和C+结构体定义不同。C+的结

35、构体实际就是一个特殊的类,在C+中变量a的定义为:A a (没有带struct)。为了让宏CLASS()定义的“类”(结构体)比较接近C+中定义的类,把struct 通过typedef 方法让 className 隐式包含了struct。2.2、宏CTOR(type) ,在有动态内存分配的情况下, 其定义为: #define CTOR(type) void* type#_Setting(type*); void* New_#type() struct type *cthis; cthis = (struct type *)malloc(sizeof(struct type); return t

36、ype#_Setting(cthis); void* type#_Setting(type *cthis) 也就是CTOR(type)代表了“void* type#_Setting(type*); void* New_#type() ” 这段代码,其中已经包含了一个动态内存分配函数和半个 type#_Setting(type *cthis);结合CTOR(type)FUNCTION_SETTING (f1, f2);END_CTOR就可以知道,CTOR() 和 END_CTOR 之间包含了两个完整的函数,一个动态内存分配函数New_type() 和构造函数 type_Setting().在没有

37、动态内存分配的情况,则表示 “void* type#_Setting(type*)”,即半个函数,组FUNCTION_SETTING (f1, f2); 和 END_CTOR 组合成一个完整的函数,也就是实现对象与其方法函数实体的关联。2.3、宏New(type)这是动态对象分配函数,宏定义为:#define New(type) New_#type()其中#表示连接字符的符号。比如New(classA),先是被替换为New_#classA(), 因为#是连接符号,故变成 New_classA(). 即为宏定义的动态内存分配函数和构造函数,实现了定义的同时也构造了(这很接近C+的模式了)。2.4

38、、宏CLASS_CTOR(type,obj)定义:CLASS_CTOR(type,obj) type#_Setting(&obj)其实是 void* type#_Setting(type*) 宏函数的另一种写法,定义该宏主要是把宏和类从一个字符串中分离出来便于书写和理解。CLASS_CTOR(类名, 对象名)必须要遵守这个规则,否则会出错。2.5、宏BASE_CTOR(base)定义:BASE_CTOR(base)CLASS_CTOR(base, cthis- base);该宏是在派生类的构造函数内用,不能在其他地方使用,也不能独立使用。因为该宏包含有cthis指针。该指针只有在CTOR()

39、. END_CTOR 之间才能引用,cthis 是CTOR()宏内部定义的指针。2.6 宏INTERFACE( type ) 和 宏 IMPLEMENTS(type)定义:#define INTERFACE(type) typedef struct type type; struct type和CLASS()宏的含义一样,单独定义主要是强调其定义的是接口。接口对应的实现的宏是IMPLEMENTS(type),其定义很简单,就是:#define IMPLEMENTS(type) type type也就是定义一个结构体变量,这个结构体类型是type,这个结构体变量名也是type。第3章:活字印刷简

40、单工厂模式在印刷术发明前,人们的印刷书是一个很艰巨的工程,先是请雕刻师将每一页的文字刻在木板上,然后再一页一页的印刷。如果在雕刻过程中,错了一个字或者要改动一个字,该页面的木板又得重新雕刻。印刷结束后,这些雕刻的木板也就没用扔掉,前面雕刻的工作全部废弃。新的一本书的印刷前,这些雕刻工作又得从头再来 今天看起来觉得古人好笨,汉字常用的就是那么几千个,一个个的独立雕刻也不费多少功夫,而雕刻一本本书,动辄少就几万字,多则几十万甚至百万字。一个活字印刷就那么难想到吗?想想我们的软件开发,很多时候,我们何尝不是“雕刻”(编码)一整个软件,编译然后“印刷”(拷贝)给各个用户呢。当用户需求改变时,我们又得重

41、新“雕刻”(重新修改代码),然后再编译“印刷”给用户。想想自己嘲笑古人的笨,回过头来看看自己做的软件开发何尝不是很笨呢?幸运的是后来毕昇发明了活字印刷,每个汉字的独立雕刻。印刷时候把用到的字组合成文章,只要雕刻一次,以后多次重复使用,如果文章修改,就只要更换修改部分的印刷字,个别生僻字没有雕刻立刻雕刻也不费多大的功夫。那么我们的软件开发里是否有“活字印刷呢”?那就是简单工厂模式。下面以一个MP3播放器实例来说明简单工厂模式。3.1 传统过程化设计思想按照传统过程化结构化思想,设计出的C+代码如下class MediaPlayerpublic:void play(string audioType)if (audioType = MP3)playMP3();if (audioType = Wav)playWav();MediaPlayer()private:void playMP3()cout播放 MP3文件endl;void playWav()cout播放 Wav 文件endl;在客户端的代码为:void main()MediaPlayer player;/-播放MP3player.play(MP3);/-播放 Wavplayer.play(Wav);

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!