第3章C++语言对C语言的扩充_第1页
第3章C++语言对C语言的扩充_第2页
第3章C++语言对C语言的扩充_第3页
第3章C++语言对C语言的扩充_第4页
第3章C++语言对C语言的扩充_第5页
已阅读5页,还剩49页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、C+程序设计实例教程程序设计实例教程第第3章章 C+语言对语言对C语言的扩充语言的扩充 C+语言对语言对C语言的扩充主要有变量的引用、类与对象、语言的扩充主要有变量的引用、类与对象、继承与多态、异常处理、函数与运算符重载以及模板与继承与多态、异常处理、函数与运算符重载以及模板与STL等等。等等。 在本章的内容中,关于在本章的内容中,关于const限定符、函数重载以及引用限定符、函数重载以及引用的相关知识是学习的重点,后续章节乃至实际编程开发的相关知识是学习的重点,后续章节乃至实际编程开发过程中,都将经常使用它们。过程中,都将经常使用它们。C+程序设计实例教程程序设计实例教程知识体系知识体系 本

2、章要点:本章要点:3.1灵活的变量声明灵活的变量声明3.2bool类型类型3.3函数参数的默认值函数参数的默认值3.4函数重载函数重载3.5函数重载的常见错误函数重载的常见错误3.6const限定符限定符3.7const修饰指针声明修饰指针声明3.8使用使用#define代替函数的原因和漏洞代替函数的原因和漏洞C+程序设计实例教程程序设计实例教程知识体系知识体系:3.9inline函数函数3.10一元域运算符一元域运算符:3.11名字空间与二元域运算符名字空间与二元域运算符:3.12使用使用using引入标识符和引入名字空间引入标识符和引入名字空间3.13类型转换类型转换3.14new、new

3、 和和delete、delete 运算符运算符3.15引用概述引用概述3.16引用参数引用参数3.17返回引用返回引用C+程序设计实例教程程序设计实例教程3.1灵活的变量声明灵活的变量声明在在C语言中,程序块中变量的声明必须放在程序块所有执行语语言中,程序块中变量的声明必须放在程序块所有执行语句之前。而句之前。而C+语言的变量声明非常灵活,语言的变量声明非常灵活,它允许变量声明它允许变量声明和执行语句在程序块中交替出现和执行语句在程序块中交替出现,只要保证变量声明在变量只要保证变量声明在变量使用之前就可以。使用之前就可以。 例如,下面的例如,下面的C+语言程序片段作为语言程序片段作为C语言程序

4、将不能通过编语言程序将不能通过编译。译。 int a; a=0; int b;/声明在声明在a=0;之后之后 b=0;C+程序设计实例教程程序设计实例教程值得值得注意注意的是,如果在程序中使用的是,如果在程序中使用goto语句进行跳转时,语句进行跳转时,最好不要跳过变量声明语句。使用最好不要跳过变量声明语句。使用goto语句跳过变量声语句跳过变量声明并初始化的语句是编译错误;使用明并初始化的语句是编译错误;使用goto语句跳过没进语句跳过没进行初始化的变量声明语句,虽然不是编译错误,但会给行初始化的变量声明语句,虽然不是编译错误,但会给阅读者没有声明变量的错觉。阅读者没有声明变量的错觉。请仔细

5、阅读请仔细阅读3.1这个例子这个例子:C+程序设计实例教程程序设计实例教程1 /3.1 goto语句跳过变量声明 2 #include 3 int main() 4 5 goto L1; 6 int a;/int a=0;直接初始化将出现编译错误 7 a=0; 8 L1: 9 a=1;10 couta=a、大于等于、大于等于=、小于、小于、小于等于、小于等于3);int b=(53);这时,这时,a被初始化为被初始化为1,b被初始化为被初始化为0。C+程序设计实例教程程序设计实例教程 C+语言为保存“真”、“假”值提供了bool数据类型,称为布尔型。bool型数据可以和int型数据相互转换。非

6、0的int型数据转换为bool型的1(代表“真”),0值的int型数据转换为bool型的0(代表“假”);bool型的1转换为int型后还是1,bool型的0转换为int型后还是0。另外,C+语言还补充了关键字true和false作为bool型常量,分别表示1和0。C+程序设计实例教程程序设计实例教程程序程序3.2对上面关于对上面关于bool型的阐述进行了验证。型的阐述进行了验证。1 /3.2 bool类型类型 2 #include 3 int main() 4 5 bool b5=0,1,false,true; 6 7 for(int i=0;i5;+i) 8 coutbi=bi ; 9 c

7、outendl;10 11 coutsizeof bool:tsizeof boolendl;12 coutsizeof b:tsizeof bendl;13 14 b0=100;15 coutb0=b0endl;16 17 cout(bool)100+9:t(bool)100+9endl;18 return 0;19 显示结果:显示结果:b0=0 b1=1 b2=0 b3=1 b4=0sizeof bool: 1sizeof b: 5b0=1(bool)100+9: 10C+程序设计实例教程程序设计实例教程3.3 函数参数的默认值函数参数的默认值 一般情况下,实参的个数应该与形参的个数相同,

8、但是在C+语言中却有例外的情况。在声明函数原型时,可以为参数设置默认值。函数有多个参数时,可以给全部参数设置默认值,也可以只给部分参数设置默认值。只给部分参数设置默认值时,要求被设置默认值的参数应该出现在没有默认值参数的右侧。也就是说,参数列表可以看成两部分,左边部分的参数没有默认值,右边参数有默然值。 C+程序设计实例教程程序设计实例教程 例如: f1(int,int,int);/正确,所有参数没有默认值 f2(int=1,int=2,int=3);/正确,所有参数有默认值 f3(int,int=2,int=3);/正确,有默认值的参数在没有默认值参数的右侧 f4(int,int=2,int

9、);/错误,有默认值的参数没在没有默认值参数的右侧 当函数调用时,从左向右匹配参数,如果实参个数不足,使用默认值来补充。程序3.3验证这一点。C+程序设计实例教程程序设计实例教程1 /3.3 函数参数的默认值函数参数的默认值 2 #include 3 void f(int,int=1,int=2,int=3); 4 int main() 5 6 /f();错误,函数错误,函数f至少提供至少提供1个参数个参数 8 cout提供提供1个参数:个参数:endl; 9 f(0);11 cout提供提供2个参数:个参数:endl;12 f(0,10);13 14 cout提供提供3个参数:个参数:end

10、l;15 f(0,10,20);16 17 cout提供提供4个参数:个参数:endl;18 f(0,10,20,30);19 return 0;20 21 void f(int a,int b,int c,int d)22 23 couta=a b=b c=c d=dendl;24 显示结果:显示结果:提供提供1个参数:个参数:a=0 b=1 c=2 d=3提供提供2个参数:个参数:a=0 b=10 c=2 d=3提供提供3个参数:个参数:a=0 b=10 c=20 d=3提供提供4个参数:个参数:a=0 b=10 c=20 d=30 C+程序设计实例教程程序设计实例教程3.4 函数重载函数

11、重载 在C+语言中,同一作用域下允许有多个同名函数的存在,但要求它们的参数列表必须不同。C+语言把这种形式称为函数重载。C+语言编译器通过函数名加上参数列表来区分同一作用域下的不同函数。参数列表相同,仅仅是返回值类型不同的同名函数不能构成重载;参数列表的类型和次序相同,仅仅是形参名不同的同名函数也不能构成重载。 重载的函数必须处于同一作用域。虽然在不同作用域中可以存在同名函数,但却不会构成函数重载。 调用重载函数时,编译器采用最佳参数匹配原则去选择该调用的函数。程序3.4示范了函数重载的使用方法。 C+程序设计实例教程程序设计实例教程1 /3.4 函数重载函数重载 2 #include 3 i

12、nt max(int,int); 4 int max(int,int,int); 5 double max(double,double); 6 main() 7 coutmax(1,2):tmax(1,2)endl; 9 coutmax(1,3,2):tmax(1,3,2)endl;10 coutmax(1.1,2.2):tmax(1.1,2.2)endl;11 return 0;12 13 int max(int a,int b)14 15 cout调用调用max(int,int)b?a:b;17 18 int max(int a,int b,int c)19 20 cout调用调用max(

13、int,int,int)endl;21 return max(max(a,b),c);22 23 double max(double a,double b)24 25 cout调用调用max(double,double)b?a:b;27 显示结果:显示结果:调用调用max(int,int)max(1,2): 2调用调用max(int,int,int)调用调用max(int,int)调用调用max(int,int)max(1,3,2): 3调用调用max(double,double)max(1.1,2.2): 2.2C+程序设计实例教程程序设计实例教程3.5 函数重载的常见错误函数重载的常见错误

14、 调用重载函数时,编译器采用最佳参数匹配原则去选择应该调用的函数。重载的函数,参数列表必须不同,有可能是参数个数不同,也可能是参数类型不同。当重载的函数参数个数不同时,函数参数的默认值可能会使原本提供多个实参才能调用的函数变得不需要那么多的实参,这时就有可能同其它版本的重载函数发生调用冲突,从而产生编译错误;当重载的函数参数类型不同时,参数的隐式类型转换可能会引发函数调用冲突,从而产生编译错误。程序3.5和3.6示范了这两种错误的发生。 默认的情况是参数多的那个C+程序设计实例教程程序设计实例教程1 /3.5 函数重载错误函数重载错误参数默认值参数默认值 2 #include 3 void f

15、(int); 4 void f(int=0,int=1); 5 int main() 6 7 f();/正确,不提供参数调用第二个正确,不提供参数调用第二个f 8 f(10,11);/正确,提供两个参数调用第二个正确,提供两个参数调用第二个f 9 /f(100);错误,提供一个参数,模棱两可的函数调用错误,提供一个参数,模棱两可的函数调用10 return 0;11 12 void f(int a)13 14 cout调用一个参数的函数调用一个参数的函数,参数参数a=aendl;15 16 void f(int a,int b)17 18 cout调用两个参数的函数调用两个参数的函数,参数参数

16、a=a,参数参数b=bendl;19 显示结果:显示结果:调用两个参数的函数调用两个参数的函数,参数参数a=0,参数参数b=1调用两个参数的函数调用两个参数的函数,参数参数a=10,参数参数b=11C+程序设计实例教程程序设计实例教程1 /3.6 函数重载错误函数重载错误数据类型隐式转换数据类型隐式转换 2 #include 3 void f(int); 4 void f(float); 5 int main() 6 7 f(1);/正确,提供正确,提供int型参数调用第一个型参数调用第一个f 8 f(1.1f);/正确,提供正确,提供float型参数调用第二个型参数调用第二个f 9 /f(1

17、.1);错误,提供错误,提供double型参数,模棱两可的函数调用型参数,模棱两可的函数调用10 return 0;11 12 void f(int a)13 14 cout调用调用int型参数函数型参数函数,int型参数型参数a=aendl;15 16 void f(float a)17 18 cout调用调用float型参数函数型参数函数,float型参数型参数a=ab?a:b;/处理整数double max(double a, double b) return ab?a:b;/处理双精度数这里,由于所处理数据的类型不同,同样的代码写了两次。C+程序设计实例教程程序设计实例教程 使用宏定义

18、#define代替函数的方法来解决上述两个问题似乎很完美。但是,由于运算符优先级等问题,使用宏定义#define代替函数会有一些漏洞。 下面的程序3.7揭示了这一点。 C+程序设计实例教程程序设计实例教程1 /3.7 #define代替函数时的漏洞代替函数时的漏洞 2 #include 3 4 #define max1(a,b) ab?a:b 5 #define max2(a,b) (a)(b)?(a):(b) 6 #define max3(a,b) (a)(b)?(a):(b) 7 8 int main() 9 10 int x=0;11 int y=2;12 int result;13 1

19、4 cout正确结果:正确结果:endl;15 result=max1(x,y);16 coutmax1(0,2):ttresultendl;17 18 cout错误结果:错误结果:endl;19 result=max1(x&y,x|y);20 coutmax1(0&2,0|2):tresultendl;C+程序设计实例教程程序设计实例教程21 22 cout正确结果:正确结果:endl;23 result=max2(x&y,x|y);24 coutmax2(0&2,0|2):tresultendl;25 26 cout错误结果:错误结果:endl;27 result=max2(y,x)+5;

20、28 coutmax2(2,0)+5:ttresultendl;29 30 cout正确结果:正确结果:endl;31 result=max3(y,x)+5;32 coutmax3(2,0)+5:ttresultendl;33 34 cout错误结果:错误结果:endl;35 result=max3(x,-y);36 coutmax3(0,-2):ttresultendl;37 couty:tttyendl;38 39 return 0;40 显示结果:显示结果:正确结果:正确结果:max1(0,2): 2错误结果:错误结果:max1(0&2,0|2): 0正确结果:正确结果:max2(0&2

21、,0|2): 1错误结果:错误结果:max2(2,0)+5: 2正确结果:正确结果:max3(2,0)+5: 7错误结果:错误结果:max3(0,-2): 0y: 0C+程序设计实例教程程序设计实例教程3.9 inline函数函数 在函数的返回值类型前面加上限定符inline会“建议”编译器在该函数的每个调用点上内联地展开函数,即在每个调用点上生成函数代码的副本。这样做可以避免发生函数调用。但是,inline函数机制不同于宏定义的“文本”替换,不会像使用宏定义一样出现漏洞。 在函数返回值类型前面的限定符inline对于编译器来说只是一个建议。编译器可以忽略它。因为,不是每个函数都适合内联展开。

22、例如,递归函数和较大的函数。 程序3.8示范了inline函数的定义方法。 C+程序设计实例教程程序设计实例教程1 /3.8 inline函数 2 #include 3 4 inline int max(int a,int b) 5 6 return ab?a:b; 7 8 9 int main()10 11 int x=0;12 int y=2;13 coutmax(0,-2):tmax(x,-y)endl;14 couty:ttyendl;15 return 0;16 显示结果:显示结果:max(0,-2): 1y: 1C+程序设计实例教程程序设计实例教程3.10 一元域运算符一元域运算符

23、: 当局部变量与全局变量重名时,局部变量会在其作用域内隐藏全局变量 . 本节的问题是:C+语言中,如何在局部访问被隐藏的全局变量。 在变量名前加上一元域运算符:代表访问全局变量。 程序3.9说明了一元域运算符:的使用方法。C+程序设计实例教程程序设计实例教程1 /3.9 一元域运算符一元域运算符: 2 #include 3 4 int x=1; 5 6 int main() 7 8 int x=10; 9 10 cout赋值前:赋值前:endl;11 cout局部局部 x=xendl;12 cout全局全局 x=:xendl;14 :x=100;15 x=1000;16 17 cout赋值后:

24、赋值后:endl;18 cout局部局部 x=xendl;19 cout全局全局 x=:xendl;20 return 0;21 显示结果:显示结果:赋值前:赋值前:局部局部 x=10全局全局 x=1赋值后:赋值后:局部局部 x=1000全局全局 x=100C+程序设计实例教程程序设计实例教程3.11 名字空间与二元域运算符: 在C+语言中,全局域中的标识符(变量名、类型名、函数名以及模板名等)必须唯一。 这就意味着,不同开发者独立开发的程序模块合并在一起时(之前没有统一的标识符命名规范),或者在一个程序中使用不同厂商提供的库时,难免会有全局域中标识符命名冲突的情况存在。为了避免或解决该问题,

25、C+语言建议声明全局标识符时使用名字空间(namespace)。 C+程序设计实例教程程序设计实例教程 域运算符:作为一元运算符使用时,帮助访问全局域的标识符(程序3.9示范了使用一元域运算符访问全局变量)。域运算符:作为二元运算符使用时,左操作数是标识符所属的名字域,右操作数是名字域包含的标识符,明确指出要使用哪个名字域的标识符。例如: namespace1:x 其中namespace1为名字空间名,x为变量名,代表名字空间namespace1中声明的变量x。程序3.10示范了名字空间和二元域运算符的使用方法。C+程序设计实例教程程序设计实例教程1 /3.10 名字空间名字空间 2 #inc

26、lude 4 int x=1; 5 void f(); 7 namespace namespace1 8 9 int x=2;10 void f();11 12 13 namespace namespace214 15 int x=3;16 void f();17 19 int main()20 21 f();22 cout x=xendl;23 C+程序设计实例教程程序设计实例教程24 namespace1:f();25 cout x=namespace1:xendl;27 namespace2:f();28 cout x=namespace2:xendl;29 return 0;30 32

27、 void f()33 34 cout名字空间外名字空间外;35 36 37 void namespace1:f()38 39 cout名字空间名字空间namespace1;40 42 void namespace2:f()43 44 cout名字空间名字空间namespace2;45 显示结果:显示结果:名字空间外名字空间外 x=1名字空间名字空间namespace1 x=2名字空间名字空间namespace2 x=3C+程序设计实例教程程序设计实例教程3.12使用使用using引入标识符和引入名字空引入标识符和引入名字空间间 在程序的某个域中采用“名字空间名域运算符标识符”的形式使用标识符

28、似乎有些麻烦,我们可以使用关键字using为该域引入频繁使用的标识符。某个域引入外来标识符后,就像在本域内声明的标识符一样,如果再在该域声明或引入同名标识符,将出现重复命名的编译错误,在该域的子域内声明同名标识符,将在子域内隐藏被引入的标识符。程序3.11示范了如何使用using引入标识符。C+程序设计实例教程程序设计实例教程1 /3.11 using引入标识符引入标识符 2 #include 3 4 namespace namespace1 5 6 int x=1; 7 void f(); 8 9 10 namespace namespace211 12 int x=2;13 void f(

29、);14 15 16 using namespace1:x;17 using namespace2:f;18 /int x;错误,与错误,与16行引入的变量重名行引入的变量重名19 int main()20 C+程序设计实例教程程序设计实例教程21 cout引入引入 x=xendl;/引入引入namespace1:x22 f();/引入引入namespace2:f23 cout x=namespace2:xendl;/未引入未引入24 25 int x=10;/局部局部x隐藏隐藏namespace1:x26 cout局部局部 x=xendl;/输出局部输出局部x27 return 0;28 2

30、9 30 void namespace1:f()31 32 cout名字空间名字空间namespace1;33 34 35 void namespace2:f()36 37 cout名字空间名字空间namespace2;38 显示结果:显示结果:引入引入 x=1名字空间名字空间namespace2 x=2局部局部 x=10 C+程序设计实例教程程序设计实例教程3.13类型转换类型转换在C+/C语言中,当使用某种类型表达式为另外一种类型变量赋值时,需要进行类型转换,这种转换有时是显式的,有时是隐式的。但无论是隐式类型转换还是显式类型转换,被转换类型的表达式为某个变量时,都不会改变被转换变量的数据

31、类型和取值,而只是返回了一个转换目标类型的临时变量。例如: int i; double d=2.5; i=1.5;/隐式类型转换 i=(int)1.5;/显式类型转换 i=d; /隐式类型转换 i=(int)d; /显式类型转换 上例中隐式类型转换与显式类型转换的结果是等价的,类型转换不会改变double型变量d的类型和取值。C+程序设计实例教程程序设计实例教程 程序3.12示范了static_cast的使用方法。 1 /3.12 static_cast 2 #include 3 using std:cout; 4 using std:endl; 5 int main() 6 7 coutst

32、atic_cast(1.5)=static_cast(1.5)endl; 8 return 0; 9 显式结果:显式结果:static_cast(1.5)=1 C+程序设计实例教程程序设计实例教程3.14 new、new 和delete、delete 运算符 C语言中,使用malloc函数申请动态内存,使用free函数释放动态内存。C+语言中,还可以使用new、new 运算符申请动态内存,使用delete和delete 运算符释放动态内存。 使用malloc函数和new 运算符申请恰好存放100个double型数据的动态内存的写法分别如下: double *p,*q; p=(double*)m

33、alloc(sizeof(double)*100); q=new double100;C+程序设计实例教程程序设计实例教程实际上,使用new、new 运算符成功申请内存时,系统将做以下3件事情:1. 分配申请的内存;2. 根据初始值初始化已分配的内存(对于为自定义类型对象(变量)申请内存的情况,将会在已分配的内存上调用自定义类型某个版本的构造函数,关于自定义类型和构造函数,可参见第4章);3. 返回已分配的内存的首地址。 C+程序设计实例教程程序设计实例教程 使用free函数、delete和delete 运算符释放非动态内存将使程序崩溃。例如: int a; int *p=&a; free(p

34、);/错误,将引起程序崩溃 delete p; /错误,将引起程序崩溃 C+程序设计实例教程程序设计实例教程 对于自定义类型来说,new、new 运算符申请内存后,会在该内存上调用自定义类型的构造函数;delete和delete 运算符在释放内存之前,会在该内存上调用自定义类型的析构函数(析构函数的相关内容,可参见4.12节)。当指向动态内存的指针指向单个变量时,使用delete运算符释放,当指向动态内存的指针指向数组时,使用delete 运算符释放。例如: int *p=new int(100);/p指向单个变量 delete p;/使用delete p=new int100;/p指向数组

35、delete p;/使用delete C+程序设计实例教程程序设计实例教程3.15引用概述引用概述 C+语言允许为变量定义引用,定义引用相当于给这个变量起了一个别名,实际上b就是a,只是起了个别名而已。引用和指针一样,都可以用来间接访问被引用(或指向)的变量。与指针相比,使用引用间接访问的语法更加优雅。定义引用时,需要在引用名前加“&”符号。使用引用间接访问时,直接使用引用名。 程序3.16示范了引用的使用方法。C+程序设计实例教程程序设计实例教程1 /3.16 使用引用使用引用 2 #include 3 using std:cout; 4 using std:endl; 5 int main

36、() 6 int a=0; 8 int &b=a;/b是是a的引用的引用 9 const int &c=a;/c是是a的常引用的常引用11 couta=aendl;12 coutb=bendl;13 coutc=cendl;14 15 cout&a=&aendl;16 cout&b=&bendl;17 cout&c=&cendl;19 b=1;20 /c=1;常引用不能作左值常引用不能作左值22 couta=aendl;23 coutb=bendl;24 coutc=cendl;25 return 0;26 显示结果:显示结果:a=0b=0c=0&a=0012FF7C&b=0012FF7C&c

37、=0012FF7Ca=1b=1c=1C+程序设计实例教程程序设计实例教程3.16引用参数 C语言中,函数参数是按值传递的,函数调用时会在函数的栈区生成函数实参的副本。在函数中修改参数值,不会对实参产生任何影响,这是对实参的一种保护措施。如果需要在函数中修改某个属于函数作用域之外的变量时,C语言的做法是传递待修改变量的指针。 程序3.17验证了这一点。C+程序设计实例教程程序设计实例教程1 /3.17 按值传递的按值传递的swap函数函数 2 #include 3 using std:cout; 4 using std:endl; 5 6 void swap(int,int); 7 void s

38、wap(int*,int*); 8 int main() 9 int x=1;11 int y=2;12 cout程序开始时程序开始时endl;13 coutx=x,y=yendl;14 15 swap(x,y);16 coutx=x,y=yendl;17 18 swap(&x,&y);19 coutx=x,y=yendl;20 return 0;21 C+程序设计实例教程程序设计实例教程22 void swap(int a,int b)23 24 int t=a;25 a=b;26 b=t;27 cout调用swap(int,int)后endl;28 29 void swap(int *p,int *q)30 31 int t=*p;32 *p=*q;33 *q=t;34 cout调用swap(int*,int*)后endl;35 显示结果:显示结果:程序开始时程序开始时x=1,y=2调用调用swap(int,int)后后x=1,y=2调用调用swap(int*,int*)后后x=2,y=1C+程序设计实例教程程序设计实例教程 C+语言中,允许函数参数通过传递引用的方式,来传递实参的“正本”。这样在函数中访问实参的引用就相当于访问实参变量本身。 程序3.18中的swap函数利用引用参数交换两个变量的

温馨提示

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

评论

0/150

提交评论