版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第七章异常及其处理(exception and its handling7.1程序运行错误及其处理程序在运行中可能出错,例如在除法运算中用0作除数、求负数的开方根、在计算机监控系统中所采集的数据越限,等等。当程序出错时,一般要求用户进行 处理,如重新输入数值或给出新的控制量等。必要时则中断程序。程序首先应检 测到出错,然后才能提示用户进行处理或由程序自动进行处理。传统的错误处理方式唯有依靠函数返回提示错误用的局部标志数据或者全局 标志数据来提示出错(全局数据的安全性差,极易受到破坏)。这类做法的困难是 程序只能在函数返回主程序后才能检查标志数据。错误处理的一种新的方式是使用“异常”(excep
2、tion)。异常处理是由程序设计 语言提供的运行时刻错误处理的一种方式。一旦程序出现错误,随即引发和抛出“异常”,程序能在一处或多处合适的地方自动地捕获异常并进行必要的处理。例1求负数的开方根时传统的错误处理方式:/ sqrt_negative_1.cpp/ error occurs when the square root of a negative number is calculated/ system subroutine used#include <iostream.h>#include <math.h> / ptototype: double sqrt( d
3、ouble );#include <stdlib.h> / ptototype: void exit(int);double sqroot(double number)if ( number < 0 )cout << "Error! negative input number : " << number << 'n'cout << "Program terminated!" << 'n'exit( -1 );return sqrt( number
4、 ); /system subroutinevoid main()cout<<"Sqrt of 1.5129 is "<<sqroot(1.5129)<<endl;cout<<"Sqrt of -4 is "<<sqroot(-4)<<endl;cout<<"Sqrt of 16 is "<<sqroot(16)<<endl;/* Results:Sqrt of 1.5129 is 1.23Error! negative inp
5、ut number : -4Program terminated!*/以上程序中,当准备求取负数的平方根时,就出错,程序非正常结束。为使程序非正常结束,须要调用系统子程序exit( ),其函数原型在头文件stdlib.h 内。其中主函数中第二句运行过程中,因调用函数sqroot(-4)B导致程序意外中断。但在sqroot(-4)前的字符串"Sqrt of-4 is ”却没有显示。这类现象将在以后众多程 序中出现。它是由于输出语句的整体性所决定的。 请见第八章§ 8.1.2.2“非缓冲输出流”中的详细解释。例 2第五章§ 5.3.1.3“除法运算符重载”中的例 1该
6、程序中的子程序double division:operator / ( double denominator ) if ( denominator = 0 ) cout<<"attempted to divide by zero"<<endl; return -999999;return (numerator/denominator); 将-999999 的返回值作为错误标志。 void main() double numerator, denominator;double result;division num(numerator);result
7、= num/denominator;/i.e. result=num. operator / ( denominator )if ( result = -999999 ) cout << "The quotient is meaningless!" << endl;cout << "Try again!" << endl;主函数 main( )在子函数 double division:operator / ( double denominator )返回主函数后立即检查返回值,如发现出错,就加以显示。如果程
8、序中出错地方较多,这类处理方法就有其局限性:当调用函数的级联数量较多(即一个函数调用下一个函数,而下一个又调用再下一个的级联方式)而又需要在其它地方(例如上级的上级的上级)统一进行处理时,逐级传递错误码太繁琐。因此须要借助于异常处理。请参阅后面本章§ 7.2.1 “抛出异常”中的例 3中的程序exception_5.cpp。 例 3 依靠异常来处理求负数开方根的例子 (当然此例中并不一定需要异常处理) :/ exception_sqrt_1.cpp/ exception occurs when the square root of a negative number is calcu
9、lated#include <iostream.h>#include <math.h> / ptototype: double sqrt( double );/#include <stdlib.h> /不再需要 exit( )double sqroot(double number)if ( number < 0 ) throw number; /exception objectreturn sqrt( number ); /system subroutine void main() try cout<<"Sqrt of 1.512
10、9 is "<<sqroot(1.5129)<<endl;cout<<"Sqrt of -4 is "<<sqroot(-4)<<endl;cout<<"Sqrt of 16 is "<<sqroot(16)<<endl;catch ( double ) / exception handlercout << "Error! negative input number" << 'n'cout
11、<< "Program terminated!" << 'n'/exit( -1 );/因已到程序结尾,故不再需要此函数/* Results:Sqrt of 1.5129 is 1.23Error! negative input number Program terminated!*/一种较好的编程方式是首先编写正常运行的代码,然后再添加用于处理 各类异常情况的语句。7.2 异常及其处理7.2.1 抛出异常从上节例2中可以看出,当监测到程序出错时,就抛出异常。其格式为: try监测到(或在被调用的程序中监测到)程序出错时, throw
12、异常对象;其中被抛出的异常对象可以是预定义数据类型(例如int、double char*等)的变量及其指针和引用,但更经常使用的是各种异常类的对象及其指针和引用。使用这些异常类对象的优点是能够提供更多关于程序错误的信息,包括处理各类 错误的方法。这些异常类可以是系统所提供的.更多情况下可以是用户自己定义应该注意:此处要求一定在try程序块中或它所调用的函数中抛出异常。以下是不在try程序块中而在try程序块所调用的函数中抛出异常的例子:例1在try程序块所调用的函数quotient()中抛出异常的例子/ exception_1.cpp/ A simple exception handling
13、example./ Checking for a divide-by-zero exception/ and throwing an intetger as an exception#include <iostream.h>/ Definition of function quotient. Demonstrates throwing/ an exception when a divide-by-zero exception is encountered. double quotient( double numerator, double divisor )if ( divisor
14、 = 0 ) throw divisor;被抛出的异常对象是预定义类型即double型数据return numerator / divisor;/ Driver programvoid main()/ the try block wraps the code that may throw an/ exception and the code that should not execute/ if an exception occurstry cout << "The quotient of 18/9 is " << quotient ( 18, 9
15、) << endl;cout << "The quotient of 18/0 is " << quotient ( 18, 0 ) << endl;cout << "The quotient of 4.5/9 is " << quotient ( 4.5, 9 ) << endl;catch ( double dd ) / exception handlercout << "Exception : divisor " << d
16、d << " used!" << endl;/* Results:The quotient of 18/9 is 2Exception : divisor 0 used!*/从以上例子中可以看出,当程序不出错时,程序按照顺序控制结构逐条语句 地向下执行,并返回除法运算结果。而当程序出错时(即当除数为零时) ,程序就 在抛出异常处中断,不再执行以后的语句(不执行第三句),并跳转至catch程序 块再继续往下执行程序。例2使用系统的异常类class exception为止匕,须包含头文件exception,/ exception_3.cpp/ same
17、as exception_1.cpp, only differing in/ throwing an object of a class instead of a double value#include <iostream.h>#includeexception,/ Definition of function quotient. Demonstrates throwing/ an exception when a divide-by-zero exception is encountered.double quotient( double numerator, double d
18、ivisor )if ( divisor = 0 ) throw exception();被抛出的异常对象是异常类即 class exception勺对象,/class exception is declared in the include file <exception> return numerator / divisor;/ Driver programvoid main()try cout << "The quotient of 18/9 is " << quotient (18, 9 ) << endl;cout
19、<< "The quotient of 18/0 is " << quotient ( 18, 0 ) << endl;cout << "The quotient of 4.5/9 is " << quotient ( 4.5, 9 ) << endl;catch ( exception ex ) / exception handler cout << ex.what( ) << 'n'/* Results:The quotient of 18
20、/9 is 2Unknown exception */以上程序中class exceptions系统所提供的异常类,在抛出异常时建立该异常 类exception的对象。为使用class exception在程序中应包含头文件exception,, 在§7.3中将会详细介绍它。catch程序块中内容将在下一小节§7.2.2中介绍。以上程序中,当出现异常时,抛出异常,程序流即自动退出 try程序块,进入 catch程序块,进行处理后即进入 catch程序块以后的语句,不再继续执行 try程 序块中抛出异常语句后的其他语句(上例中不再执行第三条语句“ quotient (4.5,
21、 9 )”)。以上程序中无法显示异常内容,但只需将以上程序略加修改,即可显示异常 内容。如exception_4.cpp(未显示整个程序)中,只需将 double quotient( int numerator, int divisor )函数的第 旬“ if ( divisor = 0 )throw exceptio,); ”改为:“if ( divisor = 0 ) throw exceptio, "Divide-by-zero exception");使用系统的异常类的对象并初始化”即可!也就是在建立 class exception的对象时,使用字符串"d
22、ivide-by-zero exception,将该异常对象的字符串数据初始化,输入用于显示异常性质的字符串。在调用异常对象中的 what()函数时就能显示该字符串。这就获得如下更明确的运行结果:/* Results:The quotient of 18/9 is 2Divide-by-zero exception*/以前提到过,当函数级联调用时,使用显示出错的函数返回值,要逐级向上 递送,很不方便。而使用异常处理就方便了。例3函数级联调用时的异常处理/ exception_5.cpp/ cascaded invocation of sub-routines#include <iostr
23、eam.h>#include <exception>/ Definition of function quotient. Demonstrates throwing/ an exception when a divide-by-zero exception is encountered. double quotient( double numerator, double divisor )if ( divisor = 0 ) throw exception( "Divide-by-zero exception");/使用系统的异常类return numer
24、ator / divisor;double h( double numerator, double divisor )double result = quotient( numerator, divisor );cout << "function h( ) in return path!" << endl;return result;double g( double numerator, double divisor )double result = h( numerator, divisor );cout << "functi
25、on g( ) in return path!" << endl;return result;double f( double numerator, double divisor )double result = g( numerator, divisor );cout << "function f( ) in return path!" << endl;return result;/ Driver programvoid main()try cout << "The quotient of 18/9 is
26、 " << f ( 18, 9 ) << endl;cout << "The quotient of 18/0 is " << f ( 18, 0 ) << endl;cout << "The quotient of 4.5/9 is " << f ( 4.5, 9 ) << endl;catch ( exception ex ) / exception handlercout << ex.what( ) << 'n&
27、#39;/* Results:function h( ) in return path!function g( ) in return path!function f( ) in return path!The quotient of 18/9 is 2Divide-by-zero exception*/以上程序中正常调用函数的路径是: main( ) -> f( ) -> g( ) -> h( ) ->quotient( ) , 在函数返回时则采取相反路径,即 quotient( ) -> h( ) -> g( ) -> f( ) -> mai
28、n( ) 。但在出现异常时,也即调用主函数中以下语句cout << "The quotient of 18/0 is " << f ( 18, 0 ) << endl;时,就不再按步就班,而是直接从 quotient (泅回至main()中的catch程序块。其流程如下图所示:其中正常运行流程引发异常流程表示函数调用路径*表示正常返回路径- 表示出现异常时的返回路径7.2.2 捕获异常捕获异常以便进行处理时,通常使用 catch程序块,其格式为:catch (数据或类的对象)程序块可在该程序块中显示相关信息和进行必要处理。例1使用异常检查
29、整型数组下标越限/ exception_7.cpp/使用异常后查整型数组下标越限#include <iostream.h>int arr = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10;int LEN; / number of elementsdouble f(int i)if ( (i>=LEN) | (i<0)throw i;return arri;void main()/ Number of elements is determined firstLEN = sizeof(arr)/sizeof(arr0);try cout<<&quo
30、t;arr1="<<f(1)<<endl;cout<<"arr4="<<f(4)<<endl;cout<<"arr-2="<<f(-2)<<endl;catch (int x) cout << "Exception:subscript "<< x<<" beyond limits (number of elements = "<<LEN<<"
31、)" << endl;/* Results:arr1=2arr4=5Exception:subscript -2 beyond limits (number of elements = 10)*/以上程序中,主程序首先自动地确定数组单元数。无论该数组类型如何,都可正确地求得。当下标越限时,就抛出异常。稍后在catch 程序块中捕获异常,并显示该下标的数值。以上是捕获一个异常的例子,以下是捕获两个异常并作不同显示的例子: 例 2 输入两个数值,两者相除,求其商。如分母为零,抛出第一类异常。如错误地输入错误类型的变量例如字符变量,则抛出第二类异常。这两类异常由一个catch
32、程序块捕获,而能作不同显示处理。/ exception_6.cpp/ different exceptions caught by one block#include <iostream.h>#include <exception>double quotient( double numerator, double divisor )if ( divisor = 0 )throw exception( "Divide-by-zero exception" );/使用系统的异常类并初始化其对象return numerator / divisor;void
33、 main()double numerator, divisor;cout << "Enter two values: "cin >> numerator >> divisor;try if (!cin)throw exception( "Wrong input type exception" );cout << "The quotient of "<<numerator<<'/'<<divisor<<" is &
34、quot;<< quotient ( numerator, divisor ) << endl;cout << "The quotient of 4.5/9 is " << quotient ( 4.5, 9 ) << endl;catch ( exception ex ) / exception handler cout << ex.what( ) << 'n'/* Three kinds of results:(1)Enter two values: 18 9The qu
35、otient of 18/9 is 2The quotient of 4.5/9 is 0.5(2)Enter two values: 18 0Divide-by-zero exception(3)Enter two values: 18 pWrong input type exception*/上例中如分母为零,抛出一个异常类对象。如错误地输入字符变量,则抛出另一 个异常类对象。这两类异常类对象的差别在于其初始化字符串内容不同。它们都能 由同一个catch程序块捕获,进行处理,显示不同内容:对第一个异常类对象显示“ Divideby-zero exception ; 对另 个异常 类对象 贝
36、 显示 “Wronginput type exception :'程序中(!cin)是“operator!("个重载运算符函数)和“cin”(一个输入流对象)的组合。当输入操作成功,(!cin)返回零值;如输入操作失败,则(!cin)返回非零值。(!cin)的功能详见第八章 B1.2.4 缓冲输入流”例5后的解释。附录十九是多个地方抛出的相同内容的异常在同一个catch程序块内处理的另一个例子。还有一种格式catch ()可用于捕获各类异常,或用于捕获其它catch ()格式所不能捕获的异常。有兴趣者可参阅附录二十。C+异异常处理机制可简叙如下:1 .如果try块中没有抛出异
37、常,则所有与try块相关的catch块将被忽略,程序跳过 所有catch块后继续运行。2 . catch块一般位于try块之后。如果try块中抛出异常,try块中的剩余语句将被跳 过而忽略。程序转至其参数类型与异常类型相匹配的catch块中,由其处理该异常。执行完毕后,跳过其它catch块,再执行所有catch块以后的其它语句。3 .如果没有其参数类型与异常类型相匹配的catch块,则由catch ()块处理该异常。7.3 用干处理异常的类7.3.1 系统提供的异常类exception_2.cp叶抛出异常的语句是:if ( divisor = 0 ) throw exception();而其运
38、行结果显示异常性质为 Unknown exception而exception_3.cpp(未显示整个程序)中抛出异常的语句是 :if ( divisor = 0 )throw exception( "divide-by-zero exception");而其运行结果显示异常性质为divide-by-zero exception这是建立异常类的对象的两种不同方式。这是什么异常类?先看一下系统的异常类。系统在头文件exception (没有exception.)中声明了用于处理异常的类 exception该类的接口如下: class exception public:excep
39、tion。;exception(const char* &);exception(const exception&);exception& operator= (const exception&);virtual exception();virtual char* what( ) const; private:char* _m_what;int _m_doFree;一一exception_2.cpp中抛出异常的语句是:if ( divisor = 0 ) throw exception();它七建立对象时调用构造函数 exception。,没有任何初始化参数。而
40、字符 用“Unknown exceptions"则是该异常类构造函数的缺省参数。而exception_3.cp叶抛出异常的语句是:if ( divisor = 0 )throw exception( "divide-by-zero exception");它在建立对象时调用重载的构造函数 exception ( const char* & ),将字符串 "divide-by-zero exception"用作初始化参数, 写入 exception : _m_what字符串 中。而以后主程序中调用该对象 ex的成员函数ex.what()时
41、,加在运行结果中 显示该字符串,指出异常性质为divide-by-zero exceptions用户除使用系统的异常类之外,也可自己定义该系统异常类class exception的派生类。例1用户自己定义系统class exception勺派生异常类/ exception_derived_loop_1.cpp/ derived class of system class exception#include <iostream.h>#include <exception> double denominator;class Except_derive : public ex
42、ception一char *message; public:Except_derive(char * ptr) message = ptr; const char * what( ) const return message; void handling ( Xcout << "Enter denominator" (分母)again :"cin >> denominator; ;void main()double numerator;bool flag = true;cout << "Enter two data :
43、"cin >> numerator >> denominator;while ( flag )tryif ( denominator = 0 ) throw Except derive( "divide by zero!"); cout<< "The quotient is: " <<(numerator/denominator)<<endl;flag = false;catch ( Except derive ex ) / exception handlercout <<
44、 "Exception : " << ex.what( ) << 'n'ex.handling (); /while/* Results:Enter two data : 4 0Exception : divide by zero!Enter denominator" (分母)again : 8The quotient is: 0.5*/以上程序中使用了循环方式,当出现异常时可循环运行,以便要求用户再次输 入正确数据。只当输入的两个数据都正确时,程序才给出运算结果并正常结束。7.3.2 用户自定义异常类上例只说明用户可定义系
45、统异常类的派生类,但并无实际意义。还不如用户 自己定义异常类。如下例:例1在给定温度条件下进行除法运算。先检查温度,如温度过高或过低,则调 整温度至给定范围。然后在除法运算中检查零除数。异常类的基类用于处理零除 数;异常类的派生类则用于处理温度过高或温度过低,并能自动地每次将温度调 整10度。/ exception_derived_loop_2.cpp/ user-defined class except and its derived classes#include <iostream.h>#define MAX_T 28#define MIN_T 16int temperatu
46、re;double denominator;class exceptchar *message;public:except (char * ptr) message = ptr; const char * what( ) const return message; virtual void handling ( ) cout << "Enter a non-zero denominator again :"cin >> denominator; void action ( ) cout << "Exception : "
47、; << what( ) << 'n'handling" ;class except_derive : public except一public:except_derive(char * ptr) : except (ptr) virtual void handling ( ) if ( temperature > MAX_T )cout <<“启动温控系统,将温度降至 "<< (temperature -= 10) << endl; elsecout << “启动温控系统,将温度
48、升至"<< (temperature += 10) << endl;double quotient( double numerator, double denominator ) if ( denominator = 0 ) throw except( "divide by zero!");return numerator / denominator;void main() double numerator, result;bool flag = true;char * mes_low = "Temperature too low
49、!"char * mes_high = "Temperature too high!"cout << "Measured temperature :"cin >> temperature;cout << "Enter numerator and denominator :"cin >> numerator >> denominator;while ( flag ) try if ( temperature > MAX_T )|( temperature <
50、; MIN_T )throw except derive( temperature > MAX T )?( mes high ):( mes low ); result = quotient ( numerator, denominator );cout << "The quotient is: " << result << endl;flag = false;/ The following order should not be reversed catch ( except derive ex ) ex.action( ); c
51、atch ( except ex )ex.action( ); / while/* At least three kinds of results:(1)Measured temperature : 20Enter numerator and denominator : 2 4The quotient is: 0.5(2)Measured temperature : 40Enter numerator and denominator : 4 8Exception : Temperature too high!启动温控系统,将温度降至30Exception : Temperature too h
52、igh!启动温控系统,将温度降至20The quotient is: 0.5(3)Measured temperature : 5Enter numerator and denominator : 4 0Exception : Temperature too low!启动温控系统,将温度升至15Exception : Temperature too low!启动温控系统,将温度升至25Exception : divide by zero!Enter a non-zero denominator again : 4The quotient is: 1*/当以上程序中出现异常时,任何一个捕获块都调
53、用基类的 action( ) ,而此action( )函数能够根据不同对象指针来调用相应的虚函数handling( ), 实现第五章中所述“多态性”中的“派生类成员函数的定向调用” 。另外,同一个派生类同时用于处理温度过高或过低,并区别地采取相应措施。上面程序中,捕获程序块的顺序不能颠倒为:catch ( except ex )ex.action( ); catch ( except_derive ex ) ex.action( ); 这时编译系统将给出警告为:warning: 'class except_derive' is caught by base class (
54、9;class except')这样一来,其运行结果将不正确,成为:(2)Measured temperature : 40Enter numerator and denominator : 4 8Exception : Temperature too high!Enter a non-zero denominator again : 4Exception : Temperature too high!Enter a non-zero denominator again : 2Exception : Temperature too high!Enter a non-zero denom
55、inator again :这是因为第一个捕获程序块也能捕获异常派生类的对象,从而导致出错。为何第一个捕获程序块也能捕获异常派生类的对象,但却又给出错误运行结果?见下例: 例 2 形参为基类对象的函数所使用实参为派生类对象时的错误/ obj_inh_1.cpp/ To show object of base class can't be inherited#include <iostream.h>class Pointdouble x, y;public:Point (double i, double j) x=i; y=j; virtual double Area( )
56、const return 0; ;class Rectangle : public Pointdouble w, h;public:Rectangle (double i, double j, double k, double l):Point (i, j) w=k; h=l; double Area( ) const return w*h; ;void fun(Point s)cout<<s.Area( )<<endl;void main()Point p (5, 6);Rectangle rec (3.5, 15.2, 5, 28);cout<<&quo
57、t;Area of Point is :"fun (p);cout<<"Area of Rectangle is :"fun (rec);/* Result:Area of Point is : 0Area of Rectangle is : 0 (当函数形参是对象而非对象指针时,无法调用派生类部 分的虚函数)*/程序中fun()的形参是基类class Poin田勺对象,但它也能使用派生类对象作为 实参,即fun (rec)。但因其形参已定义为基类对象,因此函数体内的s.Area()只能调用基类的Area()函数,得出错误的运行结果。此处 fun (r
58、ec)是合法的但却错 误的。因止匕,在exception_derived_loop_2.cppl序中,如错误地将catch ( except ex ) ex.action( ); 放置于前,则它既会捕获异常基类又会捕获异常派生类的对象。而在捕获异常派 生类对象时,将导致错误的运行结果。因此它也是是合法的但却错误的。7.3.3 异常类基类指针和引用的继承以上 *.3.2"用户自定义异常类”例1的exception_derived_loop_2.cp沸序 中,为了捕获两个不同类(基类和派生类)的对象,使用两1caich程7块,即:catch ( except_derive ex ) ex
59、.action( ); catch ( except ex ) ex.action( ); 这两个程序块的形参都是异常类的对象。能否合并为一个,例如catch()程序块?可以!但此合并后的程序块无法捕获对象名称,也就无法区别并调用相应类 的对象的虚函数handling(),因这涉及基类对象的继承问题。第五章中曾提到, 函数的“按数值调用”中,派生类对象无法继承基类对象,但却能继承基类对象 的指针和引用。因此须求助于基类对象指针或引用。所以为了合并这两个 catch 程序块,必须使用异常类基类的指针或引用而不是基类对象本身。如下:例1异常类基类指针的继承/ exception_derived_l
60、oop_3.cpp/ user-defined class except and its derived classes/ 和 exception_derived_loop_2.cppf 同之处用下戈U线标出 #include <iostream.h>#define MAX_T 28#define MIN_T 16 int temperature; double denominator; class exceptchar *message;public:except (char * ptr) message = ptr; const char * what( ) const return message; virtual void handling ( ) cout << "Enter a non-zero denominator again :"cin >> denominator; void action ( ) cout << "Exception : " << what( ) << 'n
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 办公大楼幕墙施工安装合同
- 电子元器件瑕疵管理方案
- 物业管理集团福利费管理手册
- 家具行业项目招投标信息表
- 高空农业喷洒合同
- 2025个人信用贷款借款合同
- 临沂生态农场租赁合同
- 门店市场调研渠道分析
- 医用高值耗材管理指南
- 智能家居大清包施工合同
- 新《安全生产法》解读PPT课件
- E车E拍行车记录仪说明书 - 图文-
- 人才梯队-继任计划-建设方案(珍贵)
- WLANAP日常操作维护规范
- 《健身气功》(选修)教学大纲
- 王家岩隧道工程地质勘察报告(总结)
- GE公司燃气轮机组支持轴承结构及性能分析
- 《昆明的雨》优质课一等奖(课堂PPT)
- 油气田地面建设工程ppt课件
- 电动蝶阀安装步骤说明
- 全自动电镀流水线操作说明书(共12页)
评论
0/150
提交评论