第一篇:第1章 命名空間與異常處理
版本控制頁
版本控制表
序號 版本號 V0.00 版本性質 初稿 一校 二校 10.16.2008
2008.10.30
孔祥萍 趙元
王文叢
創建時間
建議人
修訂人
修改日期
修改內容簡述
備注
第1章 命名空間與異常處理
本章主要內容:
? 命名空間的定義 ? 命名空間的訪問 ? 異常處理的概念 ? 異常處理的機制 ? 多層級間的異常處理 ? 異常處理的堆棧操作
本章重點:
? 命名空間的定義與命名空間的訪問 ? 異常處理的機制和實現 ? 多層級間的異常處理
本章難點:
? 命名空間的訪問
? 多層級間的異常處理 ? 異常處理的堆棧操作
學完本章您將能夠:
? 了解命名空間概念 ? 掌握命名空間定義 ? 了解異常處理的機制 ? 掌握異常處理的方法
? 掌握多層級間的異常處理方法 ? 了解異常處理中的堆棧操作
引言
在一個給定作用域中定義的每個名字在該作用域中必須是惟一的,對龐大、復雜的應用程序而言,這個要求可能難以滿足。這樣的應用程序在全局作用域中,一般有許多名字定義。由獨立開發的庫構成的復雜程序更有可能遇到名字沖突,本章用命名空間的技術來解決此類問題。
C++中的異常處理是一種靈活并且精巧的工具。它克服了C語言的傳統錯誤處理方法的缺點,并且能夠被用來解決一系列運行期的錯誤。但是,異常處理也像其他語言特性一樣,很容易被誤用。為了能夠有效的使用這一特性,了解運行期機制如何工作以及相關的性能花費是非常重要的。
1.1 命名空間
1.1.1 命名空間的定義
命名空間定義以關鍵字namespace開始,后接命名空間的名字。命名空間名字后面由大括號括住的一塊聲明和定義區域構成,可以在命名空間中放入可以出現在全局作用域的任意聲明:類、變量(以及它們的初始化)、函數(以及它們的定義)、模板以及其他命名空間。
namespace GameCollege {
class Matrix { /*...*/ };
void Inverse(matrix &);
const double PI = 3.1416;} 這段代碼定義了名為 GameCollege的命名空間,它有3個成員:一個類、一個函數、一個常量。
像其他名字一樣,命名空間的名字在定義該命名空間的作用域中必須是惟一的。命名空間可以在全局作用域或其他作用域內部定義,但不能在函數或類內部定義。命名空間作用域不能以分號結束。
定義在命名空間中的實體稱為命名空間成員。像任意作用域的情況一樣,命名空間中的每個名字必須引用該命名空間中的惟一實體。因為不同命名空間引入不同作用域,所以不同命名空間可以具有同名成員。在命名空間中定義的名字可以被命名空間中的其他成員直接訪問,命名空間外部的代碼必須指出名字定義在哪個命名空間中。在命名空間之外使用空間的成員必須用空間名字進行修飾。
#include
與其他作用域不同,命名空間可以在幾個部分中定義。命名空間由它的分離定義部分的總和構成,命名空間是累積的。一個命名空間的分離部分可以分散在多個文件中,在不同文本文件中的命名空間定義也是累積的。當然,名字只在聲明名字的文件中可見,這一常規限制繼續應用,所以,如果命名空間的一個部分需要使用定義在另一文件中的名字,仍然必須聲明該名字。
1.1.2 嵌套命名空間
一個嵌套命名空間,即是一個嵌套作用域,其作用域嵌套在包含它的命名空間內部。嵌套命名空間中的名字遵循常規規則:外圍的命名空間中聲明的名字被嵌套命名空間中同一名字的聲明所屏蔽。嵌套命名空間內部定義的名字局部于該命名空間。外圍的命名空間之外的代碼只能通過限定名訪問嵌套命名空間中的名字。
嵌套命名空間可以改進庫中代碼的組織:
namespace GameCollege
// 外圍的命名空間 {
namespace QueryLib
// GameCollege的嵌套命名空間QuerLib
{
class Query { /*...*/ };
Query operator&(const Query&, const Query&);
//...}
namespace Bookstore
// GameCollege的嵌套命名空間Bookstore {
class Item_base { /*...*/ };
class Bulk_item : public Item_base { /*...*/ };
//...} } 命名空間GameCollege現在包含兩個嵌套命名空間:名為QueryLib的命名空間和名為Bookstore的命名空間。
當程序庫提供者為了防止庫中每個部分的名字與庫中其他部分的名字起沖突的時候,嵌套命名空間是很有用的。
嵌套命名空間中成員的名字由外圍命名空間的名字和嵌套命名空間的名字構成。例如,嵌套命名空間QueryLib中聲明的類的名字是:
GameCollege::QueryLib::Query 1.1.3 命名空間的訪問
如:命名空間名namespace_name::member_name,成員名這樣引用命名空間的成員無可否認是很麻煩,特別是命名空間名字很長的時候。可以使用更簡潔的方式使用命名空間的成員。
? using 聲明
【實例1-1】using聲明
#include
cout << "Hello, World!" << endl;
return 0;} 使用using聲明能使命名空間std中的名字cout、endl在當前作用域中可見,可以無須限定符std::而使用名字cout、endl。using聲明中引入的名字遵循常規作用域規則。從using聲明點開始,直到包含using聲明的作用域的末尾,名字都是可見的。外部作用域中定義的同名實體被屏蔽。簡寫名字只能在聲明它的作用域及其嵌套作用域中使用,一旦該作用域結束了,就必須使用完全限定名。using聲明可以出現在全局作用域、局部作用域或者命名空間作用域中。類作用域中的using聲明局限于被定義類的基類中定義的名字。
? 命名空間別名
可用命名空間別名將較短的同義詞與命名空間名字相關聯。例如:
namespace GameCollegeLib {
} const MyClass cMyClass = MyClass();void PrintfMyClass(const MyClass& myClass);class MyClass { public:
};void SetValue(int v){ iValue = v;} int GetValue()const { return iValue;} int iValue;MyClass(): iValue(0){}
private: 這樣的長命名空間名字,可以像下面這樣與較短的同義詞相關聯:
namespace gc = GameCollegeLib;命名空間別名聲明以關鍵字namespace開頭,接(較短的)命名空間別名名字,再接 =,最后接原來的命名空間名字和分號。如果原來的命名空間名字是未定義的,程序將會出錯。
【實例1-2】命名空間別名
#include
namespace gc = GameCollegeLib;
int main(){
std::cout << gc::cMyClass.GetValue()<< std::endl;gc::MyClass myClass;
myClass.SetValue(45);
gc::PrintfMyClass(myClass);
} return 0;上例程序中gc是GameCollegeLib的別名,可以通過gc訪問GameCollegeLib命名空間中成員。
一個命名空間可以有許多別名,所有別名以及原來的命名空間名字都可以互換使用。
? using 指示的形式
“using指示”以關鍵字using開頭,后接關鍵字namespace,再接命名空間名字。如果該名字不是已經定義的命名空間名字,程序將會出錯。
using namespace std;
“using指示”使得特定命名空間所有名字可見,沒有限制。短格式名字可從“using指示”點開始使用,直到出現“using指示”的作用域的末尾。
【實例1-3】using指示的形式訪問命名空間
namespace GameCollegeLib {
int i = 16, j = 15, k = 23;
// 命名空間其他成員 } int j = 0;void manip(){
using namespace GameCollegeLib;// using 指示GameCollegeLib空間中名稱全部可見
++i;
// 設置GameCollegeLib::i為17
++j;
// 錯誤:名稱沖突,無法確定是全局j還是GameCollegeLib::j
++::j;
// 設置全局變量j為1
++GameCollegeLib::j;// 設置GameCollegeLib::j為16
int k = 97;
// 定義局部變量k將覆蓋GameCollegeLib::k
++k;
// 設置局部變量k賦值為98 } manip中的“using指示”使manip能夠直接訪問GameCollegeLib中的所有名字:使用它們的簡化形式,該函數可以引用這些成員的名字。
GameCollegeLib的成員看來好像是在定義GameCollegeLib和manip的作用域中定義的一樣。如果在全局作用域中定義GameCollegeLib,則GameCollegeLib的成員看來好像是聲明在全局作用域的一樣。因為名字在不同的作用域中,manip內部的局部聲明可以屏蔽命名
空間的某些成員名字,局部變量k屏蔽命名空間名字GameCollegeLib::k,在manip內部對k的引用沒有二義性,它引用局部變量k。
命名空間中的名字可能會與外圍作用域中定義的其他名字沖突。例如,對manip而言,GameCollegeLib命名空間的成員j看來好像聲明在全局作用域中,但是,全局作用域存在另一名為j的對象。這種沖突是允許的,但為了使用該名字,必須顯示指出想要的是哪個版本,因此,在manip內部的j使用是有二義性的:該名字既可引用全局變量又可引用命名空間 GameCollegeLib的成員。
為了使用像j這樣的名字,必須使用作用域操作符指出想要的是哪個名字。可以編寫 ::j 來獲得在全局作用域中定義的變量,要使用GameCollegeLib中定義的j,必須使用它的限定名字GameCollegeLib::j。
“using指示”注入來自一個命名空間的所有名字,它的使用是不可靠的:只用一個語句,命名空間的所有成員名就突然可見了。雖然這種方法看似簡單,但也有它自身的問題。如果應用程序使用許多庫,并且用“using指示”使得這些庫中的名字可見,那么,全局命名空間污染問題就會重新出現。
1.2 異常處理在C++中的實現
1.2.1 異常處理的概念和使用條件
程序運行中的某些錯誤(或意外情況)不可避免但可以預料。例如,假設y變量是一個除法運算或者模運算的除數,那么當變量y為0時,是一種嚴重的錯誤(即出現異常),需要得到處理并將錯誤反饋給設計者,可以在程序中添加如下形式的測試語句來達到這樣的目的:
if(y == 0){
std::cout << “Error occuring--Divided by 0!”;exit(1);} 若出現y值為0的情況,則用戶程序將進行干預,比如先在屏幕上給出適當的錯誤提示信息,然后退出程序停止運行等。這種處理工作本質上就是異常處理。從這里可以看出,異常處理就是從發生異常情況的地方停止,不再進行正常的程序流程,而是轉而執行特定的異常處理流程。
1.2.2 異常處理的實現
C++中提供的對異常進行處理的機制,那就是在程序中使用try、catch和throw。
【實例1-4】在函數中使用異常機制
請看如下程序,其中使用了try、catch和throw來對除以0或模0所產生的異常進行處理。程序要求輸入兩個整數i1、i2以及一個運算符op(“/”或者“%”),而后進行相應運算并對所出現的異常進行處理。
#include
using std::cout;using std::cin;using std::endl;
void main(){
try
{
// try 程序塊為“受監控”的塊,塊中所拋出的異常
// 將被本try塊后的某一個catch塊所捕獲并處理
int i1, i2;
char op;
cout << “Input I1 I2 OP:”;
cin >> i1 >> i2 >>op;// 輸入兩個整數i1、i2 以及一個運算符op
if(op == '/')
{
// 分母為0 時,拋出一個字符串:char*類型的異常
// 所拋出的異常將被隨后的catch塊捕獲并處理
if(i2 == 0)
throw “Divided by 0!”;
// 正常情況(分母非0)的處理
cout << i1 << “ / ” << i2 << '=' << i1/i2 << endl;
}
else if(op == '%')// 限制op只能為“/”或者“%”
{ // 分母為0 時,拋出整數i1 — int 型異常 // 所拋出的異常將被隨后的catch 塊捕獲并處理
if(i2==0)
throw i1;
cout << i1 << “ % ” << i2 << '=' << i1 % i2 << endl;// 正常情況處理
}
else
cout<<“OP error--must be '/' or '%'!”< // 再進行一些其他的處理 cout << “22 / 5=” << 22 / 5 << endl; } catch(int i) { // 捕獲“int”類型的異常并進行處理 // 輸出相關的異常信息后結束本catch塊 cout << “Error occuring--” << i << “ % 0 ” << endl; } catch(char *str) // 捕獲“char *”類型的異常并進行處理 { // 輸出相關的異常信息后結束本catch塊 cout<<“Error occuring--”< } // 異常處理結束后,均轉到此處執行該語句 cout<<“End main function!”< Input I1 I2 OP:33 5 % 33 % 5=3 22 / 5=4 End main function!再次運行,顯示結果為: Input I1 I2 OP:33 0 / Error occuring--Divided by 0!End main function!注意:通過throw拋出異常后,系統將跳轉到與所拋出的實參(表達式)類型完全匹配的catch塊去執行,而執行完catch塊后將不再返回,繼而轉到catch塊序列的最后一個catch 塊的下一語句處去執行。 對實際問題進行處理的程序中,還會碰到多種多樣的產生異常(或錯誤)的情況。例如,磁盤中的文件被移動或缺少所需文件時將導致無法打開,內存不足使得通過new無法獲取所需要的動態空間,用戶提供了不恰當的輸入數據等。為使程序具有更好的容錯能力并體現出程序的健壯性,設計程序時,應該充分考慮程序執行過程中可能發生的各種意外情況(即異常),并對它們進行恰當的處理。也就是說,當異常出現后,要盡可能地讓用戶程序來進行干預,排除錯誤(至少給出適當的錯誤提示信息),而后繼續運行程序。 下面對try、catch和throw的功能及其使用時要注意的內容做進一步說明: 1) 通過try可構成try塊,用于標記運行時可能出現異常的程序代碼。也就是說,try程序塊在運行時將成為“受監控”的代碼塊,其中所拋出的任何異常(包括:在try 塊中直接拋出的異常,以及通過所調用的“下層”函數而間接拋出的各種異常)都將被捕獲并處理。 注意:拋出異常是通過throw 語句來完成的。try 塊的使用格式如下: try { //“受監控”的語句序列(通常包含拋出異常的throw 語句)} 2) 通過catch可構成所謂的catch塊,它緊跟在try塊的后面,用于監視并捕獲運行時可能出現的某一種類(類型)的異常并對此種異常進行具體的處理(處理程序代碼包含在catch塊之中)。即catch程序塊將監視并捕獲處理程序異常,若沒有異常出現的話,catch程序塊將不被執行。若準備處理多種類型的異常,要同時給出一個連續的catch塊序列,屆時系統將通過按序逐一“比對”所拋出的異常類型(既可是系統預定義的基本類型,也可是用戶自定義的某種類型)來確定執行該catch塊序列中的哪一塊。 catch 塊的使用格式如下: catch(/*欲捕獲的異常類型及形參名字*/){ //對該類型異常的具體處理語句序列 } 注意:如果catch塊的具體處理語句序列中根本不使用形參(對應值)的話,則catch塊首括號中可以只給出一個異常類型而不必給出形參名字。另外,還允許在catch塊首括號中僅寫上3 個點符號, 即“catch(…)”,其使用含義為:該catch塊將捕獲任何類型的異常。也就是說,它與任何一種異常類型都可以匹配成功。若使用這種catch塊的話,它應該是catch塊序列的最后一塊,否則,其后的所有catch塊都將起不到任何作用(永遠不會被“匹配”成功。因為系統是按序與catch塊序列中的每一塊逐一進行“對比”的)。 拋出異常的throw語句的使用格式為: throw 表達式 通常使用“表達式”的特殊情況,例如,一個變量或對象、一個常量或字符串等。系統將根據表達式的值類型來與各catch塊首括號中形參的異常類型進行“比對”,若“匹配”成功(要求類型完全一致,系統并不自動進行類型轉換),則跳轉到那一catch塊去執行,即進行相應的異常處理。若所有匹配都不成功,則將自動去執行一個隱含的系統函數“abort()”來終止整個程序的運行。 更確切地說,throw語句將把運行時遇到的異常事件信息通知給相匹配的異常處理catch塊代碼(throw后的“<表達式>”,實際上起著實參的作用,它代表的正是異常事件信息,而catch塊首括號中設立的正是所對應的形參。與函數調用類似,通過throw拋出異常后,也同樣有一個實參與形參相結合的過程,形參與實參結合后,catch塊中處理的實際上是throw語句所提供的實參信息。但與函數調用不同的是,函數調用完成后仍要返回到調用處繼續執行,而throw語句所進行的“調用”實際上是帶有實參的跳轉,跳轉到的目標是形參和實參完全匹配的一個catch塊,而執行完catch塊后將不再返回,繼而轉到catch塊序列的最后一個catch塊的下一語句處去執行。另外注意,catch塊必須有且僅有一個形參的說明(可以缺少形參名字,但不可以缺少其類型),throw語句后攜帶的也只是一個相對應的實參(表達式)。 1.3 多級多層捕獲與處理機制 1.3.1 多級多層處理的機制 在程序中的層次級別指的是函數間的層層調用關系。在這個調用中被調函數拋出異常,而被主調函數捕獲,那么這種情況下的異常處理就稱為是多級多層處理。C++的異常處理中是允許處理多級多層情況的。具體如下: 1)允許拋出異常的語句處于捕獲與處理異常的catch塊所在函數的“下屬層次”,例如,可以在主調函數中處理異常,而在被調函數中拋出異常。也就是說,若在本層次的函數中無法處理所拋出的異常的話,系統總會自動沿著“調用鏈”一直向上傳遞異常。系統將首先找到異常拋出句throw 所處函數的“父輩”函數,進一步可能又要去找其“祖輩”函數。 【實例1-5】多層間的異常處理 #include int nExc = 0; unsigned short sProduct = sNum1 * sNum2; // 當結果超出數據表達范圍時就拋出異常 if(sProduct < sNum1 || sProduct < sNum2) { throw nExc; } else { } int main(){ unsigned short s1 = 50000, s2 = 40000; unsigned short sProduct; try { sProduct = numMul(s1, s2); printf(“乘積=%dn”, sProduct);catch(int nExc){ printf(“錯誤代碼為:%dn”, nExc); } return 0;} return sProduct; } } 程序運行,結果如下: 錯誤代碼為:0 2)允許在同一程序中使用多個try塊,而且這些try塊可以處于不同的位置并具有不同的層次級別。拋出異常后,系統將首先在相應的低層次級別的try塊后的catch塊序列中尋找匹配,若不成功,將自動沿著“調用鏈”向上傳遞該異常,并在上一層次的try塊后的catch塊序列中繼續尋找匹配。直到最終匹配成功,或者已到達了最高層次的main函數后仍不成功時,則自動調用系統隱含函數“abort()”來終止整個程序的運行。 改寫上例中的main()函數,對于拋出的異常不做處理。 #include unsigned short s1 = 50000, s2 = 40000; unsigned short sProduct; sProduct = numMul(s1, s2); printf(“乘積=%dn”, sProduct); return 0;} 程序運行后,系統報錯后結束。 1.3.2 多級多層處理的綜合實例 【實例1-6】對用戶提供不恰當輸入數據的異常進行處理 輸入一個限定范圍內的整數,若輸入數據不處于限定范圍之內時,則視為程序運行異常,而后拋出并捕獲處理這些異常。若輸入正確,則在屏幕上顯示出所輸入的整數。另外,在程序中自定義一個異常類myExcepCla,以方便對異常的處理。 對輸入數據所限定的范圍如下:只允許輸入-50~50之間除去0、11與22之外的那些整數。具體對異常的處理設定為: 若輸入值為0,則拋出一個“char*”類異常 — 顯示“main-catch::Exception : value equal 0!”; 若輸入值小于-50,則拋出一個自定義類myExcepCla異常 — 顯示“main-catch::Exception : value less than-50!”; 若輸入值大于50,則拋出一個“char*”類異常 — 顯示“InData-catch::Exception : value greater than 50!”; 若輸入值為11,則利用輸入值拋出一個int 型異常 — 顯示“InData-catch::Caught INT exception!i=11”; 若輸入值為22,則拋出一個double型異常 — 顯示“main-catch::Caught unknown exception!”。 要求程序使用兩個try塊,一個處于main函數中,而另一個則處于被main函數調用的InData函數之中,它們具有不同的位置并具有不同的層次級別。main函數中try塊后的catch塊序列捕獲并處理“char*”、myExcepCla以及“其他”任何類型的異常;而InData函數中try塊后的catch 塊序列則捕獲并處理int與“char*”類型的異常。 #include { char message[100];public: // 構造函數,實參帶來私有字符串數據message myExcepCla(char* msg) { strcpy(message, msg); } // 成員函數,獲取私有數據message字符串 char* GetErrMsg() { return message; } };void InData();//函數聲明 void main(){ // 處于main中的try程序塊,它為“受監控”的程序塊 try { InData();// 調用自定義函數InData,其中可能拋出異常 cout << “End try block!” << endl; } catch(char * str)// 捕獲“char *”類型的異常并進行處理 { cout << “main-catch::” << str << endl; } catch(myExcepCla ob) { // 捕獲“myExcepCla”類型的異常并進行處理 cout << “main-catch::” << ob.GetErrMsg()<< endl; } catch(...) { // 捕獲“其他”任何異常并進行處理 cout << “main-catch::” << “Caught unknown exception!” << endl; } // 本層次的某個異常處理結束后,// 均轉到此處執行該語句 cout << “End main function!” << endl;} void f(int val){ // 自定義函數f,負責判斷val 是否為11 或22,// 輸入值為11,拋出一個int 型異常 if(val == 11) throw val; // 輸入值為22,拋出一個double型異常 if(val == 22) throw 123.86;} 注意:f中所拋出的int型異常,將首先被自動沿著“調用鏈”向上傳遞到其“父輩”函數InData,而在InData中的catch塊序列中,該異常恰好被匹配成功而得到處理。f中所拋出的double型異常,首先也被自動沿著“調用鏈”向上傳遞到其“父輩”函數InData,而在InData中的catch塊序列中無法匹配成功又進一步被傳遞到其“祖輩”函數main,在main中與“catch(...)”匹配成功而得到處理。 void InData(){ int val; cout << “Input a INTEGER(from-50--50, excpt 0、11、22):”; cin >> val; if(val == 0)// 若輸入值等于0,拋出“char*”類異常,在main中被捕獲處理。 throw “Exception : value equal 0!”; try { // 處于InData中的try程序塊,它為“受監控”的另一個程序塊 if(val<-50) { myExcepCla exc(“Exception : value less than-50!”); // 該異常將被main中try 后的“catch(myExcepCla ob)” // 所捕獲處理 throw exc; } if(val > 50) throw “Exception : value greater than 50!”;// 在本try 后的catch 塊序列中被捕獲處理 else f(val);// 被調函數f 中可能拋出異常 cout << “OK!value=” << val << endl;//不發生異常時,屏幕顯示出輸入值val } // 捕獲“int”類型的異常并進行處理 catch(int i) { cout << “InData-catch::” << “Caught INT exception!i =” << i << endl; } // 捕獲“char *”類型的異常并進行處理 catch(char * str) { cout << “InData-catch::” << str << endl; } } 注意:InData函數中try塊后的某一個catch塊被執行后(異常被處理結束后),將結束InData函數,返回到其主調函數main的try程序塊的InData函數調用語句的下一語句處,即將接著去執行main中的“cout<<“End try block!”< 顯示結果為: Input a INTEGER(from-50--50, excpt 0、11、22):0 main-catch::Exception : value equal 0!End main function!第二次執行: Input a INTEGER(from-50--50, excpt 0、11、22):88 InData-catch::Exception : value greater than 50!End try block!End main function!第三次執行: Input a INTEGER(from-50--50, excpt 0、11、22):50 OK!value=50 End try block!End main function!本實例程序中使用了兩個try塊,一個處于main函數中,而另一個則處于被main函數調用的InData函數之中,它們具有不同的位置并具有不同的層次級別。拋出異常后,系統總是首先在相應的低層次級別(如本例的InData函數)的try塊后的catch塊序列中尋找匹配,若不成功,再自動沿著“調用鏈”向上傳遞該異常,并在上一層次(如本例的main函數)的try塊后的catch塊序列中繼續尋找匹配。 另一個注意點是:若程序中含有多個不同位置并具有不同層次級別的try塊時,一旦異常被某一個層次的catch塊所捕獲,在執行完那一catch塊后,系統的繼續運行“點”將是本層次catch塊序列之最后一個catch塊的下一語句處(若那里不再有其他語句時,則結束那一函數而返回到上一層次的主調函數中)。 本程序還自定義了一個異常類myExcepCla,通過對它的使用,可建立起一種對異常進行處理的統一模式。 1.4 異常處理中的堆棧展開 C++進行異常處理時,總要自動地進行如下所述的一個“堆棧展開”過程:每當拋出一個異常后,系統首先找到能捕獲處理該異常的catch塊(注意,其中可能自動沿著“調用鏈”多次向上傳遞該異常,并假定在某一層次的try塊后的catch塊序列中找到了相匹配的catch塊),緊接著系統要利用所拋出的對象(throw句中的“實參”)對相應catch塊的“形參”進行“初始化”,而后將立即檢查從拋出異常的那一try塊的塊首到該異常被拋出之間已構造,但尚未析構的那些處于堆棧中的局部對象(與變量)。若有,系統將自動對這些局部對象進行相應的退棧與析構處理(通過自動調用各對象的析構函數來完成,析構對象的順序與構造它們的順序恰好相反),再去執行相應catch塊中的代碼完成對異常的處理。 系統之所以要這樣做,是因為異常處理機制中,通過throw語句拋出異常后,系統實際上是要找到并“跳轉”到捕獲異常的catch塊去執行,而且在執行完那一catch塊后將不再返回(到throw語句之后),繼而轉到catch塊序列的最后一個catch塊的“下一語句”處去執行。正是由于這種“跳轉”后的不再返回,當拋出異常的throw語句處于某一下屬層次的局部作用域(如某個局部塊作用域或某個函數作用域)之中時,throw的“跳轉”實際上相當于跳出了那些作用域,所以系統將自動檢查在那些作用域中已經構造但尚未析構的處于堆棧中的局部對象(與變量),并自動進行相應的退棧與析構處理。 【實例1-7】分析以下程序執行后會顯示出什么結果 注意系統對局部塊作用域中的局部對象ob1和ob2所進行的自動析構處理。程序中說明了一個具有顯式構造函數和析構函數的自定義類ClaA,并在其中顯示目前已經進入該構造函數或析構函數的提示信息(因為要通過輸出信息來觀察系統提供的自動析構處理功能)。 編寫main函數,并在其中設置局部塊作用域,且說明ClaA自定義類的局部對象ob1和ob2,之后通過拋出“char*”類型的異常“跳轉”出該局部塊作用域(此時系統將對局部對象進行自動析構處理)。 由于要拋出并處理異常,將main中的程序段置于try塊的塊體之中,并添加捕獲“char*”類型異常的catch塊。 本實例的重點在于了解異常處理過程中的“堆棧展開”,以及對象的自動析構處理功能。 #include using std::cout;using std::cin; using std::endl; class ClaA { }; void main(){ } // 捕獲“char *”類型的異常并進行處理 catch(char * str){ } cout<<“After throw, in block-statement!End block-statement!”< throw “throwing 'char*' exception in block-statement!”;cout << “Throwing exception, in block-statement!” << endl;// 局部于塊的對象ob1和ob2 均被分配在系統的堆棧中 ClaA ob1(“ob1”), ob2(“ob2”);cout<<“Begin main function!”< // try 程序塊為“受監控”的程序塊 cout << “Enter try-block!” << endl;// 定義一個局部塊作用域 { cout << “Begin a block-statement!” << endl;~ClaA(){ } cout << “Destructing ClaA obj--” << s << endl;ClaA(char * str){ } cout << “Constructing ClaA obj--” << str << endl;strcpy(s, str);char s[100];public: } } cout<<“Execution resumes here.End main function!”< cout<<“In catch-block, deal with: ”< Begin main function!Enter try-block!Begin a block-statement!Constructing ClaA obj--ob1 Constructing ClaA obj--ob2 Throwing exception, in block-statement!Destructing ClaA obj--ob2 Destructing ClaA obj--ob1 In catch-block, deal with: throwing 'char*' exception in block-statement!Execution resumes here.End main function!注意:上一程序中,拋出異常的throw語句處于一個局部塊作用域內,throw的“跳轉”實際上相當于跳出了那個局部塊作用域(“跳轉”到相對應的那一catch塊而不再返回),所以系統將自動檢查在那一局部塊作用域中已經構造,但尚未析構的處于堆棧中的局部對象。如本例的ob1和ob2,并自動對它們進行相應的退棧與析構處理(析構順序為ob2而后是ob1)。 實際上,當拋出異常的throw語句處于下屬層次的某個函數作用域之中時,throw的“跳轉”就相當于跳出了那個函數作用域(而不再返回),那時系統同樣也將自動檢查在哪一函數作用域中已經構造,但尚未析構的處于堆棧中的局部對象,并自動進行相應的退棧與析構處理。 例如,若將本例程序main函數中的try塊改寫為: try { cout << “Enter try-block, calling fun!” << endl;fun();} 在程序中添加如下形式的一個fun函數的話,則系統會自動對ob1與ob2進行相應的退棧與析構處理,大家可作為一個練習去完成,并上機進行調試驗證。 void fun(){ cout << “Begin fun!” << endl; ClaA ob1(“obj1”), obj2(“ob2”); cout << “Throwing exception, in fun!” << endl; throw “throwing 'char*' exception in fun!”; cout << “After throw, in fun!End fun!” << endl;} 注意:fun 函數中所拋出的異常,是由其主調函數main 處的catch塊所捕獲并處理的。本章小結 本章介紹了命名空間概念,如何使用命名空間解決名字沖突問題。如何定義命名空間以及如何使用命名空間成員。在進行復雜系統設計過程中,名字沖突問題是不可避免的,命名空間技術可以很好的解決此類問題。嵌套命名空間可以防止庫中每個部分的名字與庫中其他部分的名字沖突的問題。對于命名空間的訪問有“using聲明”、“命名空間別名”、“using 指示”等方法。由于“using指示”使得命名空間中的名字暴露在全局區域中,所以要盡量避免使用。本章還介紹了C++中的異常處理,C++中采用異常處理機制的原因和實現方法,以及實際程序設計時會遇到多層級異常處理的問題。此外還介紹了C++中異常處理時的堆棧操作,使大家更能了解異常處理對程序穩定性的影響,并掌握在程序中使用異常處理的方法,從而使大家設計的程序更加健壯。 自測習題 判斷試題 1.當程序中產生異常時,程序一定會被強制結束。()2.異常只在try塊中產生,在非try塊中不會產生。() 3. 在catch塊首括號中僅寫上3個點符號,即catch(?)時此塊不處理任何異常。()4.若try塊后找不到相應的catch塊來處理異常,則程序將忽略這個異常繼續運行。()5.在同一程序中,try塊的數量一定和catch塊的數量一樣多。()問答題 6.解釋using聲明和using指示符的區別。7.考慮下面的代碼例子: namespace Exercise { } int ivar = 0;//1 int ivar = 0;double dvar = 0;const int limit = 1000; void manip(){ //2 double dvar = 3.1416;int iobj = limit + 1;++ivar;++::ivar;} 如果將命名空間Exercise成員的using聲明放在 //1 處那么會對代碼中的聲明和表達式有什么影響?如果放在 //2 處呢?當用using指示符代替命名空間Exercise的using聲明時,答案又是什么? 課后作業 1.輸入一組數,實現一個累加和函數,當累加和超過數據的表示范圍時,產生異常。2.在自己項目中定義自己命名空間,并分別用using聲明、命名空間別名、using指示對命名空間成員進行引用。 System 命名空間 類 Activator 包含特定的方法,用以在本地或從遠程創建對象類型,或獲取對現有遠程對象的引用。 AppDomain 表示應用程序域,它是一個應用程序在其中執行的獨立環境。不能繼承此類。AppDomainSetup 表示可以添加到 AppDomain 的實例的程序集綁定信息。 AppDomainUnloadedException 在嘗試訪問已卸載的應用程序域時引發的異常。ApplicationException 發生非致命應用程序錯誤時引發的異常。ArgumentException 在向方法提供的其中一個參數無效時引發的異常。 ArgumentNullException 當將空引用(在 Visual Basic 中為 Nothing)傳遞給不接受它作為有效參數的方法時引發的異常。 ArgumentOutOfRangeException 當參數值超出調用的方法所定義的允許取值范圍時引發的異常。 ArithmeticException 因算術運算、類型轉換或轉換操作中的錯誤而引發的異常。 Array 提供創建、操作、搜索和排序數組的方法,因而在公共語言運行庫中用作所有數組的基類。 ArrayTypeMismatchException 當試圖在數組中存儲類型不正確的元素時引發的異常。AssemblyLoadEventArgs 為 AssemblyLoad 事件提供數據。Attribute 自定義屬性的基類。 AttributeUsageAttribute 指定另一特性類的用法。無法繼承此類。 BadImageFormatException 當 DLL 或可執行程序的文件圖像無效時引發的異常。BitConverter 將基礎數據類型與字節數組相互轉換。Buffer 操作基元類型的數組。 CannotUnloadAppDomainException 卸載應用程序域的嘗試失敗時引發的異常。CharEnumerator 支持循環訪問 String 并讀取它的各個字符。 CLSCompliantAttribute 指示程序元素是否符合公共語言規范(CLS)。無法繼承此類。Console 表示控制臺應用程序的標準輸入流、輸出流和錯誤流。無法繼承此類。ContextBoundObject 定義所有上下文綁定類的基類。 ContextMarshalException 在嘗試將對象封送過上下文邊界失敗時引發的異常。ContextStaticAttribute 指示靜態字段的值是特定上下文的唯一值。Convert 將一個基本數據類型轉換為另一個基本數據類型。DBNull 表示空值。Delegate 表示委托,委托是一種數據結構,它引用靜態方法或引用類實例及該類的實例方法。DivideByZeroException 試圖用零除整數值或十進制數值時引發的異常。 DllNotFoundException 當未找到在 DLL 導入中指定的 DLL 時所引發的異常。 DuplicateWaitObjectException 當對象在同步對象數組中不止一次出現時引發的異常。EntryPointNotFoundException 因不存在項方法而導致加載類的嘗試失敗時引發的異常。Enum 為枚舉提供基類。 Environment 提供有關當前環境和平臺的信息以及操作它們的方法。不能繼承此類。EventArgs EventArgs 是包含事件數據的類的基類。Exception 表示在應用程序執行期間發生的錯誤。 ExecutionEngineException 當公共語言運行庫的執行引擎中發生內部錯誤時引發的異常。無法繼承此類。 FieldAccessException 當試圖非法訪問類中的私有字段或受保護字段時引發的異常。FlagsAttribute 指示可以將枚舉作為位域(即一組標志)處理。 FormatException 當參數格式不符合調用的方法的參數規范時引發的異常。GC 控制系統垃圾回收器(一種自動回收未使用內存的服務)。 IndexOutOfRangeException 試圖訪問索引超出數組界限的數組元素時引發的異常。無法繼承此類。 InvalidCastException 因無效類型轉換或顯式轉換引發的異常。 InvalidOperationException 當方法調用對于對象的當前狀態無效時引發的異常。 InvalidProgramException 當程序包含無效 Microsoft 中間語言(MSIL)或元數據時將引發的異常。通常這表示編譯器中出現錯誤。 LoaderOptimizationAttribute 用于為可執行應用程序的主方法設置默認的加載程序優化策略。LocalDataStoreSlot 封裝內存槽以存儲本地數據。無法繼承此類。 MarshalByRefObject 允許在支持遠程處理的應用程序中跨應用程序域邊界訪問對象。Math 為三角函數、對數函數和其他通用數學函數提供常數和靜態方法。MemberAccessException 訪問類成員的嘗試失敗時引發的異常。 MethodAccessException非法嘗試訪問類中的私有方法或受保護的方法時引發的異常。MissingFieldException 試圖動態訪問不存在的字段時引發的異常。 MissingMemberException 試圖動態訪問不存在的類成員時引發的異常。MissingMethodException 試圖動態訪問不存在的方法時引發的異常。 MTAThreadAttribute 指示應用程序的 COM 線程模型為多線程單元(MTA)。 MulticastDelegate 表示多路廣播委托;即,其調用列表中可以擁有多個元素的委托。 MulticastNotSupportedException 當試圖合并不可合并的委托類型的兩個實例時引發的異常,除非操作數中有一個是空引用(在 Visual Basic 中為 Nothing)。無法繼承此類。NonSerializedAttribute 指示可序列化類的某個字段不應被序列化。無法繼承此類。 NotFiniteNumberException 當浮點值為正無窮大、負無窮大或非數字(NaN)時引發的異常。 NotImplementedException 在無法實現請求的方法或操作時引發的異常。NotSupportedException 當調用的方法不受支持,或試圖讀取、查找或寫入不支持調用功能的流時引發的異常。 NullReferenceException 嘗試取消引用空對象引用時引發的異常。 Object 支持.NET Framework 類層次結構中的所有類,并為派生類提供低級別服務。這是.NET Framework 中所有類的最終基類;它是類型層次結構的根。ObjectDisposedException 對已處置的對象執行操作時所引發的異常。ObsoleteAttribute 標記不再使用的程序元素。無法繼承此類。 OperatingSystem 表示有關操作系統的信息,如版本和平臺標識符。OutOfMemoryException 沒有足夠的內存繼續執行程序時引發的異常。OverflowException 在選中的上下文中所進行的算術運算、類型轉換或轉換操作導致溢出時引發的異常。 ParamArrayAttribute 指示方法在調用中將允許參數的數目可變。無法繼承此類。PlatformNotSupportedException 當功能未在特定平臺上運行時所引發的異常。 Random 表示偽隨機數生成器,一種能夠產生滿足某些隨機性統計要求的數字序列的設備。RankException 將維數錯誤的數組傳遞給方法時引發的異常。 ResolveEventArgs 為 TypeResolve、ResourceResolve 和 AssemblyResolve 事件提供數據。SerializableAttribute 指示一個類可以序列化。無法繼承此類。StackOverflowException 掛起的方法調用過多而導致執行堆棧溢出時引發的異常。無法繼承此類。 STAThreadAttribute 指示應用程序的 COM 線程模型是單線程單元(STA)。String 表示文本,即一連串 Unicode 字符。 SystemException 為 System 命名空間中的預定義異常定義基類。ThreadStaticAttribute 指示靜態字段的值對于每個線程都是唯一的。TimeZone 表示時區。Type 表示類型聲明:類類型、接口類型、數組類型、值類型和枚舉類型。 TypeInitializationException 作為由類初始值設定項引發的異常周圍的包裝引發的異常。無法繼承此類。 TypeLoadException 類型加載失敗發生時引發的異常。TypeUnloadedException 試圖訪問已卸載的類時引發的異常。 UnauthorizedAccessException 當操作系統因 I/O 錯誤或指定類型的安全錯誤而拒絕訪問時所引發的異常。 UnhandledExceptionEventArgs 為以下情況下引發的事件提供數據:存在一個不是由應用程序域處理的異常。 Uri 提供統一資源標識符(URI)的對象表示形式和對 URI 各部分的輕松訪問。 UriBuilder 為統一資源標識符(URI)提供自定義構造函數,并修改 Uri 類的 URI。UriFormatException 當檢測到無效的統一資源標識符(URI)時引發的異常。ValueType 提供值類型的基類。 Version 表示公共語言運行庫程序集的版本號。無法繼承此類。WeakReference 表示“弱引用”,即在引用對象的同時仍然允許對該對象進行垃圾回收。接口 IAppDomainSetup 表示可以添加到 AppDomain 的實例的程序集綁定信息。IAsyncResult 表示異步操作的狀態。 ICloneable 支持克隆,即用與現有實例相同的值創建類的新實例。 IComparable 定義通用的比較方法,由值類型或類實現以創建類型特定的比較方法。IConvertible 定義特定的方法,這些方法將實現引用或值類型的值轉換為具有等效值的公共語言運行庫類型。 ICustomFormatter 定義一種方法,它支持對象值的自定義(用戶定義)格式設置。IDisposable 定義一種釋放分配的非托管資源的方法。IFormatProvider 提供用于檢索控制格式化的對象的機制。IFormattable 提供將對象的值格式化為字符串表示形式的功能。IServiceProvider 定義一種檢索服務對象的機制,服務對象是為其他對象提供自定義支持的對象。 _AppDomain 表示應用程序域,它是一個應用程序在其中執行的獨立環境。結構 ArgIterator 表示變長參數列表;即采用可變數量的參數的函數的參數。Boolean 表示布爾值。 Byte 表示一個 8 位無符號整數。Char 表示一個 Unicode 字符。DateTime 表示時間上的一刻,通常以日期和當天的時間表示。Decimal 表示十進制數。 Double 表示一個雙精度浮點數字。Guid 表示全局唯一標識符(GUID)。Int16 表示 16 位有符號的整數。Int32 表示 32 位有符號的整數。Int64 表示 64 位有符號的整數。 IntPtr 用于表示指針或句柄的平臺特定類型。RuntimeArgumentHandle 引用變長參數列表。 RuntimeFieldHandle 使用內部元數據標記表示一個字段。 RuntimeMethodHandle RuntimeMethodHandle 是方法的內部元數據表示形式的句柄。RuntimeTypeHandle 表示使用內部元數據標記的類型。SByte 表示 8 位有符號整數。Single 表示一個單精度浮點數字。TimeSpan 表示一個時間間隔。 TypedReference 描述既包含指向某位置的托管指針,也包含該位置可能存儲的類型的運行時表示形式的對象。 UInt16 表示 16 位無符號整數。UInt32 表示 32 位無符號整數。UInt64 表示 64 位無符號整數。 UIntPtr 用于表示指針或句柄的平臺特定類型。 Void 指示不返回值的方法,即具有 void 返回類型的方法。委托 AssemblyLoadEventHandler 表示處理 AppDomain 的 AssemblyLoad 事件的方法。AsyncCallback 引用在異步操作完成時調用的回調方法。 CrossAppDomainDelegate 由 DoCallBack 使用,用于跨應用程序域的調用。EventHandler 表示將處理不包含事件數據的事件的方法。 ResolveEventHandler 表示處理 AppDomain 的 TypeResolve、ResourceResolve 和 AssemblyResolve 事件的方法。 UnhandledExceptionEventHandler表示將處理事件的方法,該事件由應用程序域不處理的異常引發。枚舉 AttributeTargets 指定可以對它們應用特性的應用程序元素。DayOfWeek 指定一周的某天。 Environment.SpecialFolder 指定用于檢索系統特殊文件夾的目錄路徑的枚舉常數。LoaderOptimization 一個枚舉,它與 LoaderOptimizationAttribute 類一起使用為可執行文件指定加載程序優化。 PlatformID 描述程序集所支持的平臺。TypeCode 指定對象的類型。 UriHostNameType 為 Uri.CheckHostName 方法定義主機名類型。UriPartial 為 Uri.GetLeftPart 方法定義 URI 的各部分。 使用DFS創建命名空間 如果想把零散的共享資源組織起來,可以使用DFS創建命名空間。以下是win7之家所介紹的建命名空間的步驟。 步驟1:打開【DFS管理】窗口,右擊【命名空間】結點,執行【新建命名空間】命令,如下圖所示。 新建命名空間 步驟2:windows7系統下載彈出【新建命名空間向導】對話框,根據向導提示填寫相關的信息,即可順利地新建命名空間。 分布式文件系統命名空間解析 近年,微軟對其分布式文件系統(Distributed File System,DFS)做了很多改良,其中的一項技術對文件系統資源提供了統一視圖。DFS重新定向了來自UNC途徑的請求,其中一個網絡驅動映射到請求資源所在的網絡共享。這樣的結果是你可以添加文件服務器到網絡或者不用影響用戶訪問文件的方式就能強化現有的文件服務器。重定向請求到文件實際位置的UNC途徑就是DFS命名空間。本質上,DFS命名空間是為用戶呈現文件服務器資源集中化視圖的統一命名空間。一個DFS命名空間由很多部分組成。DFS根DFS命名空間本質上是分等級的,最頂端的是DFS根。在實際運用中,可以認為根和命名空間是一樣的,因為根常用來指代整個命名空間。DFS根是一個共享文件,它必須存在于NTFS卷中。DFS根鏈接到一個或多個根目標,而根目標則鏈接到一個文件服務器上的UNC共享。一個DFS根可以鏈接的根目標數量由DFS根相關的命名空間類型決定。DFS命名空間有兩個類型:獨立命名空間和基于域的命名空間。獨立命名空間存儲他們在主機服務器注冊表中的配置信息。基于域的命名空間存儲在活動目錄數據庫中的信息。這個區別影響連接到DFS根的根目標數量。獨立DFS根只能包含一個單一根目標,而基于域的DFS根只包含通過多個服務器分離的多個根目標。下面的圖1展示了一個基于域的DFS根。很明顯這是基于域的,因為這個根的名字(//lab.com/namespace)反映了域的名字。中心方格顯示兩個UNC途徑,并且兩個途徑都像根目標一樣鏈接到DFS根。圖1:DFS根連接到一個或多個根目標DFS命名空間里的文件或鏈接在分級中的下一個元素是文件或鏈接(正如它有時候所指的)。在DFS命名空間中的每個文件都映射到鏈接目標,正如DFS根映射到根目標。鏈接目標指向一個映射到物理文件夾的UNC共享。在圖2 中,三個文件(文件 1、文件2和文件3)都被定義在DFS根下(注意,我已經選了文件1)。控制臺的中央窗口列出了映射到文件的鏈接目標。圖2:每個文件都映射到鏈接目標如你所見,這個鏈接目標不過是一個映射到共享文件的UNC途徑。另外要注意,在控制臺的中央窗口中,為鏈接目標展示了各種各樣的信息,包括類型、途徑和提交狀態。由于一個文件可以和不同服務器上的多個鏈接目標連接,所以提交狀態存在。這樣做了之后,你可以為鏈接目標創建一個復制組,且復制組會保持多種文件內容與其它文件之間的同步。圖3展示的就是一個有多個鏈接目標的文件。圖3:多個鏈接目標兩個鏈接目標的提交狀態都是有效的(Enabled)。這意味著DFS可以向任意一個目標指定資源請求。因此,如果一個文件服務器必須離線維修,這個服務器的提交狀態就變成無效,而DFS會停止向該服務器發送請求,直到提交狀態再次變為有效。NTFS級別的DFS命名空間上述因素組成了DFS命名空間。在圖4中,你可以看到NTFS級別的命名空間是什么樣子的。圖4:驅動C盤上的DFS內容注意名為Dfsroots的文件,它下面的那個文件就叫Namespace(命名空間)。當我創建根時DFS自動創建這些文件。Namespace文件實際上是共享的,但是文件系統隱藏了該共享。最后要注意,在命名空間下面有到文件 1、文件2和文件3的快捷鍵.這些都是在DFS管理控制臺中指定的目標文件。在圖的底部是這三個文件夾的另一個列表,它實際上是在驅動C盤上的共享文件。我剛剛提到的快捷鍵映射到這些共享文件夾。 文 山 金 文 山 豐 產 林 有 限 公 司 W E N S H A N G O L D E N W E N S H A N F O R E S T C O.,LTD.異常案件處理辦法(試行) 一目的 本辦法旨在規范指引金光紙業在文山豐產林項目公司(簡稱公司,下同)異常案件的處理,發揮各職能部門的積極性、主動性、能動性,及時、合法、合理、高效處理異常案件,營造有利于林漿紙項目發展的良好氛圍,最大限度地維護公司利益。二異常案件含義及主要案件分類界定 本辦法所稱異常案件系指妨礙林班有效經營管理以及違反國家政策和法律法規,損害公司利益,依法應承擔法律責任的案件,包括但不限于:森林火災、林地林木權屬糾紛、盜伐、盜竊、濫伐、破壞生產經營、非法放牧砍柴、濫墾、征地占地、臨時占用、非法占地、移動損壞標志、偷采礦產、其他案件(水土流失、病蟲害、凍害、水澇、旱災、風災、偷采野生植物、偷獵、非法經營木材業等)。 處理異常案件,除提請案件處理行政機關依法追究外,應當努力通過各種方式、循相關渠道取得當地政府、林漿紙(業)部門等黨政部門的支援或協助。1 森林火災 (1)森林火災系指因各種自然、人為(故意或過失)以及因暫時無法判斷之狀況發生的林地火災,云南省一般每年12月1日至次年6月15日,為全省森林防火期。每年3月1日至4月30日為全省森林防火戒嚴期。(2)森林防火期內,在森林、新造林地內,嚴禁下列活動和行為: (一)烤蜂、燒山狩獵和使用火藥搶狩獵、烤火、烘烤食品和野炊; (二)上墳燒紙、燒香、燃放鞭炮; (三)使用火把照明、吸煙; (四)其他非生產性用火。 (3)森林防火期內,確需在林區、林緣進行生產性用火的,必須經村民委員會(相當于村小組)同意,報村公所(相當于村委會)、辦事處(鄉鎮人民政府派出機構)批準。經批準進行的生產性用火,必須落實防火措施,有專人負責。 煉山造林、燒牧場,必須提前10天報縣(市、區)森林消防指揮部批準,發給用火許可證。經批準的野外用火,必須落實消防措施,按批準的時間、范圍,在三級風以下的天氣進行,由批準機關指定專人監督實施。森林防火戒嚴期內,在林區內,嚴禁一切野外用火。 (4)引起森林火災案件的責任人依法應承擔法律責任(行政處罰、賠償公司損失和追究刑事責任),并先由當地林業局或授權的當地森林公安機關(無森林公安機關的,由地方公安機關管轄,下同)或鄉鎮林業站查處;構成犯罪的,依法提請追究責任人的刑事責任。2.盜伐(1)指違反森林法及其他森林保護法規,以非法占有為目的,具有下列情形之一,數量較大的行為: (一)擅自砍伐國家、集體、他人所有或者他人承包經營管理的森林或者其他林木,以及擅自砍伐他人自留山上的成片林木; (二)擅自砍伐本單位或者本人承包經營管理的森林或者其他林木; (三)在林木采伐許可證規定的地點以外采伐國家、集體、他人所有或者他人承包經營管理的森林或者其他林木。(2)法律責任 (一)構成行政處罰的規定:不足0.5 M3或幼樹不足20株,由縣級以上林業主管部門責令補種盜伐株數10倍的樹木,沒收盜伐的林木或者變賣所得,并處盜伐林木價值3至5倍的罰款;0.5 M3以上或幼樹20株以上,責令補種盜伐株數10倍的樹木,沒收盜伐的林木或者變賣所得,并處盜伐林木價值5至10倍的罰款。 (二)構成犯罪(追究刑事責任)的規定:盜伐森林或者其他林木,數量較大的(2—5M3或幼樹100—200株),處三年以下有期徒刑、拘役或者管制,并處或者單處罰金;數量巨大的(20—50 M3或幼樹1000—2000株),處三年以上七年以下有期徒刑,并處罰金;數量特別巨大的(100—200 M3或幼樹5000—10000株),處七年以上有期徒刑,并處罰金。 (三)對公司造成的損失,責任人應承擔賠償責任。 (四)盜伐案件首先由當地林業局或授權的森林公安機關、鄉鎮林業站管轄。3.濫伐 (1)指違反森林法及其他保護森林法規,具有下列情形之一,數量較大的行為: (一)未經林業行政主管部門及法律規定的其他主管部門批準并核發林木采伐許可證,或者雖持有林木采伐許可證,但違反林木采伐許可證規定的時間、數量、樹種或者方式,任意采伐本單位所有或者本人所有的森林或者其他林木的; (二)超過林木采伐許可證規定的數量采伐他人所有的森林或者其他林木的; (三)林木權屬爭議一方在林木權屬確權之前,擅自砍伐森林或者其他林木的。(2)法律責任 (一)構成行政處罰的規定:濫伐森林或者其他林木,以立木材積計算不足2M3或幼樹不足50株的,由縣級以上林業主管部門責令補種濫伐株數5倍的樹木,并處濫伐林木價值2至3倍的罰款; 2 M3以上或幼樹50株以上,以立木材積計算2立方米以上或者幼樹50株以上的,由縣級以上人民政府林業主管部門責令補種濫伐株數5倍的樹木,并處濫伐林木價值3倍至5倍的罰款。 (二)構成犯罪(追究刑事責任)的規定:違反森林法的規定,濫伐森林或者其他林木,數量較大的(10—20M3或幼樹500—1000株),處三年以下有期徒刑、拘役或者管制,并處或者單處罰金;數量巨大的(50—100 M3或幼樹2500—5000株),處三年以上七年以下有期徒刑,并處罰金。 (三)對公司造成的損失,責任人應承擔賠償責任。 (四)盜伐案件首先由當地林業局或授權的森林公安機關、鄉鎮林業站管轄。4.權屬糾紛 (1)權屬糾紛系指因林地林木的所有權或使用權產生的爭議。(2)法律規定: (一)單位之間發生的林木、林地所有權和使用權爭議,由縣級以上人民政府依法處理。 (二)個人之間、個人與單位之間發生的林木所有權和林地使用權爭議,由當地縣級或者鄉級人民政府依法處理。 (三)當事人對人民政府的處理決定不服的,可以在接到通知之日起一個月內,向人民法院起訴。 (四)在林木、林地權屬爭議解決以前,任何一方不得砍伐有爭議的林木。 (3)林班責任人應當隨時掌握并報告權屬糾紛發生情況,發生權屬糾紛(特別是公司給付承包費、已經發包造林的林地)時,采取初步處臵措施后,應當毫無遲延地向公司提報;因權屬糾紛引起的各種異常案件均與該案合并提報。 林地權屬糾紛發生后,積極協調爭議方協商處理,簽訂協議,協商未成的,為排除對現場作業的干擾因素,建議爭議各方先行擱臵爭議,交政府部門確權處理,并不得影響我方正常作業。涉及爭議地的所得部分提存有關部門或留存我方,待爭議處理后,按權屬比例或我方原合同約定原則再行給付,根據處理結果對合同作相應變更或補簽合同。5.征地占地 (1)征地(包括征收和征用)占地系指勘查、開采礦藏和修建道路、水利、電力、通訊等工程,需占用(相對于國有土地)或征收征用(相對于集體土地)公司林地的按照規定辦理審批手續并給予補償的合法活動。(2)上述工程必須遵守下列規定 (一)用地單位應當向縣級以上人民政府林業主管部門提出用地申請(含補償協議書),經審核同意后,按照國家規定的標準預交森林植被恢復費,領取使用林地審核同意書。用地單位憑使用林地審核同意書依法辦理建設用地審批手續。占用或者征用林地未經林業主管部門審核同意的,土地行政主管部門不得受理建設用地申請; (二)占用或者征用防護林林地或者特種用途林林地面積10公頃以上的,用材林、經濟林、薪炭林林地及其采伐跡地面積35公頃以上的,其他林地面積70公頃以上的,由國務院林業主管部門審核;占用或者征用林地面積低于上述規定數量的,由省、自治區、直轄市人民政府林業主管部門審核。占用或者征用重點林區的林地的,由國務院林業主管部門審核。 (三)用地單位需要采伐已經批準占用或者征用的林地上的林木時,應當向林地所在地的縣級以上地方人民政府林業主管部門或者國務院林業主管部門申請林木采伐許可證。 (3)法律責任:未經批準或者采取欺騙手段騙取批準,非法占用土地的,由縣級以上人民政府土地行政主管部門責令退還非法占用的土地,對違反土地利用總體規劃擅自將農用地改為建設用地的,限期拆除在非法占用的土地上新建的建筑物和其他設施,恢復土地原狀,對符合土地利用總體規劃的,沒收在非法占用的土地上新建的建筑物和其他設施,可以并處罰款;對非法占用土地單位的直接負責的主管人員和其他直接責任人員,依法給予行政處分;構成犯罪的,依法追究刑事責任。超過批準的數量占用土地,多占的土地以非法占用土地論處。(4)征收征用或占用土地的,公司有權依法獲得補償;征地占地案件由縣級以上人民政府土地管理部門處理。 (5)占用公司林地,占用土地人持有征地占地審批文件,未與公司洽商處理或雖有洽商處理但未達成意見的,應取得鄉鎮人民政府、縣林漿紙、縣人民政府等部門支持,向鄉鎮林業站、土地管理部門或縣級林業局林政資源部門詳細反映、了解情況,提報縣級以上土地管理部門處理。6.臨時占用 (1)臨時占用林地系指臨時占用人基于一定需要占用公司林地向縣級以上林業行政主管部門申請批準并依法給予公司補償的活動,一般不超過 兩年。 (2)臨時占用各類林地的,按照下列規定辦理: (一)臨時占用用材林、經濟林、薪炭林林地面積不滿二公頃的,由縣級林業行政主管部門審批;二公頃以上不滿十公頃的,由地州市林業行政主管部門審批;十公頃以上不滿三十五公頃的,由省林業行政主管部門審批;三十五公頃以上的,由省林業行政主管部門審核后報國務院林業行政主管部門審批; (二)臨時占用防護林、特種用途林林地面積不滿十公頃的,由省林業行政主管部門審批;十公頃以上的,由省林業行政主管部門審核后報國務院林業行政主管部門審批; (三)臨時占用其他林地面積不滿十公頃的,由縣級林業行政主管部門審批;十公頃以上不滿三十公頃的,由地州市林業行政主管部門審批;三十公頃以上不滿七十公頃的,由省林業行政主管部門審批;七十公頃以上的,由省林業行政主管部門審核后報國務院林業行政主管部門審批。 臨時占用林地的單位和個人,應當在使用期滿后負責恢復林業生產條件并應當對林地所有者或者經營者進行補償。(3)辦理程序 (一)臨時占用單位向林地所在地縣級以上人民政府林業主管部門提出用地申請,并送有關材料占用林地的地點、面積、范圍的說明及有關資料等。 (二)經林業行政主管部門審核同意后,用地單位與林業主管部門簽訂臨時用地協議書。 (三)按規定支付補償費。 (四)經批準并交納費用后,到申請的林業主管部門辦理臨時占用林地手續。 (4)占用公司林地,占用土地人持有縣級以上林業主管部門審批文件,未與公司洽商處理或雖有洽商處理但未達成意見的,提報縣級以上林業主管部門處理。7.非法占地 (1)非法占用林地系指未經批準或者采取欺騙手段騙取批準,占用公司林地的行為。 (2)占用公司林地,未與公司洽商處理或雖有洽商處理但未達成意見,初步了解沒有發現占用人持有國家有關部門審批文件的,按非法占用案件處理,應取得鄉鎮人民政府、縣林漿紙、縣人民政府等部門支持,向鄉鎮林業站、鄉鎮土地管理部門或縣級林業局林政資源部門詳細反映、了解情況,提報縣級以上土地管理部門處理。8.破壞生產經營 (1)破壞生產經營系指由于泄憤報復(包括林地林木權屬糾紛)或其他個人原因,采用拔苗、破壞林木、損壞林道、集材道、運材道、培育生產種子苗木、貯存種子苗木木材、汽車等林業生產服務設施等方法破壞公司生產經營的行為。等行為。 (2)法律責任:除賠償公司損失外,由于泄憤報復或者其他個人目的,毀壞機器設備、殘害耕畜或者以其他方法破壞生產經營的,處三年以下有期徒刑、拘役或者管制;情節嚴重的,處三年以上七年以下有期徒刑。 (3)發生該案的,當地鄉鎮無森林公安機關派出機構的,應當按照就近原則,努力取得當地鄉鎮政府支持向當地鄉鎮地方公安機關派出機構提 報調查、采取措施,同時以《異常案件報告表》的形式提報公司處理,當地鄉鎮設有森林公安機關派出機構的,應直接提報查處。9.放牧砍柴 (1)砍柴放牧系指違反林業法規,在幼林地特種用途林地內 放牧砍柴,致使公司林地受到毀壞的行為;因泄憤報復或權屬糾紛等原因,放牧致使公司林地受到毀壞的,按放牧砍柴、權屬糾紛與破壞生產經營案件并案處理。 (2)法律責任:在幼林地和特種用途林內砍柴、放牧致使森林、林木受到毀壞的,依法賠償損失;由林業主管部門責令停止違法行為,補種毀壞株數一倍以上三倍以下的樹木。 (3)發生該案的,視情況提報縣級林業主管部門或授權的森林公安機關、鄉鎮林業站查處。10.濫墾 (1)濫墾系指毀林開墾和毀林采石、采沙、采土及其他毀林行為。(2)法律責任:,進行開墾、采石、采砂、采土、采種、采脂和其他活動,致使森林、林木受到毀壞的,依法賠償損失;由縣級林業主管部門責令停止違法行為,補種毀壞株數一倍以上三倍以下的樹木,可以處毀壞林木價值一倍以上五倍以下的罰款。(3)該案由縣級以上林業主管部門或授權的森林公安機關、鄉鎮林業站處理。11.偷采礦藏 (1)偷采礦產系指未取得采礦許可擅自采礦的行為。 (2)法律責任:未取得采礦許可證擅自采礦的,責令停止開采、賠償損失,沒收采出的礦產品和違法所得,可以并處罰款;拒不停止開采,造成礦產資源破壞的,依照刑法第一百五十六條的規定對直接責任人員追究刑事責任。 (3)偷采礦產案件由省級人民政府地質礦產主管部門處理,國家有關部門積極配合,該案無論是否取得采礦許可,只要采礦威脅、侵占、毀壞公司林地,未與公司洽商處理或雖有洽商處理但未達成實質意見的,按偷采礦產和非法占地案件并案提報處理。12.移動損壞標志 (1)移動損壞標志系指擅自移動或者毀壞林業服務標志的行為。 (2)法律責任:擅自移動或者毀壞林業服務標志的,由縣級以上人民政府林業主管部門責令限期恢復原狀;逾期不恢復原狀的,由縣級以上人民政府林業主管部門代為恢復,所需費用由違法者支付。 (3)該案由縣級以上林業主管部門或授權的森林公安機關、鄉鎮林業站處理。三 依據 根據現行法律法規、結合公司經營實際情況制訂本辦法。四 適用范圍 本辦法適用于公司所有異常案件的處理。五 處理部門及其職責 1.公司實行林政部門主導異常案件制度,林政部門的配臵可以在林務部設立,也可以逐級設立,總體負責異常案件的管理、跟蹤和督辦以及處理機制的拓展;根據案件的性質,法務部門對林政部門和林場處理異常案件進行業務指導和監督。2.林場、林政及法務部門都是處理異常案件的部門,相關部門或人員應密切配合。 (1)對公司生產經營影響不大或涉案標的2000元(含)以下的異常案件一般由林場處理;(2)對公司生產經營影響較大或涉案標的2000元以上的異常案件一般由林政部門處理; (3)對公司生產經營構成重大影響或牽連訴訟和刑事案件的一般由法務部門處理,對牽連法律問題的生產技術性異常案件僅提供法律建議;(4)經公司總(副)經理特別指示交辦的案件可不受上述金額、標準限制。 影響是否重大應當從案件是否對林班的有效經營管理構成重大影響、案件的危害程度或持續負面影響、侵權人(次)數、侵害(動機、工具、手段、面積等)、社會關注度等方面綜合判定。 3.處理部門必須堅持維護公司整體利益的原則,采取各種措施,積極、切實、高效地處理異常案件,并及時將處理過程或結果反饋至上級部門或主管,上級主管都負有對異常案件處理進行及時組織、領導、協調和支援之責任。六 處理程序及方法 (一)報告 對事后發現或對正在發生的異常案件經林場現場盡職處理后,林場應在發現后48小時內填寫《異常案件報告表》(附件1)(情況緊急的立即提報,事后補辦),根據《異常案件報告表》規定的程序和權限,報告案件發生和處理情況,由相關部門簽署案件處理意見,最后由總經理綜合多方意見,形成決策。 《異常案件報告表》中案件發生詳細情況欄根據案件性質說明定植時間、平均樹高、平均胸徑、時間、地點、人物、原因、過程、現場盡職采取了何種措施等,案發時開始,現場責任人應毫無遲延地進行線索摸查,保存有關證據材料,為案件進一步處理提供便利條件。 請求事項可包含對案件合理合法化處理的意見或建議,應盡可能詳盡,林場得根據案件性質和本辦法規定的原則合理提供具體處理方案和處理部門,以供權責主管參考。 (二)報案 案件承辦部門或人員根據立案標準及公司領導決策進行具體事項的操辦,對需向政府主管機關報案處理的,應具以書面形式,包括案件發現者、當事人、時間、地點、證人證言、損失情況及對案件的處理請求等基本內容。報案書由林政部門擬制,經法務審核;情況緊急的由林場先口頭報案。 1、構成刑事案件的,依法報主管機關查處及追究刑事責任。在公訴機關提起公訴前公司案件承辦人員可代表公司與對方當事人對損害賠償進行和解,也可在追究刑事責任進入訴訟程序后,由我司提出附帶民事訴訟,以達成追償經濟損失或持續維護林漿紙基地建設之利益。 2、尚未構成刑事案件的異常案件經總經理批準,依法報政府主管機關查處,同時通報相關單位如當地村委會、林業站。當事人因違反行政管理秩序的行為應當接受行政處罰,如限期恢復原狀、罰款、沒收違法所得等,同時因該行為而造成我方物質損失的還應承擔民事賠償責任。 (三)處理現場: 1.現場人員對正在實施的不法行為在表明身份時應立即予以制止,可采取合理有效措施以制止不法侵害繼續發生和防止損失繼續擴大,并及時電話報告上級;在事態難以控制或情況緊急時,應毫無遲延請求當地執法機關依法予以制止、扣留作案工具及扣押有關責任人員,必要時及時請當地村委會、林業站、鄉鎮政府、森林公安或當地派出所協助處理;相關部門怠于處理的,應毫無遲延地報告相關主管處臵。2.收集有關證據,對現場拍照留存,照片應一底兩片,交政府主管機關一份,公司存檔一份。 3.現場被政府主管機關確認并請示公司后再進行清理,現場遺留有財產的,在清理前應有人員看守。 (四)跟蹤案件處理情況 主要由案件承辦人員或指派人員在職權或授權范圍內跟蹤督促政府主管部門依法辦理,并及時向上級報告案情進展情況或請示處理辦法。 (五)追償損失 1.確定損失:以給我方造成的直接實際損失為準。如有評估機構作出的損失評估報告則依之,如沒有,則按我方制訂的相關規定評估。如因侵權行為造成林地永久流失的,則將我方承包期限內的預計可得利益計入損失范圍。 2.追償時間:從損失確定之日起,案件承辦人員就可代表公司對當事人提出具體的索賠要求,每次索賠時應保存有關證據,一般要求有書證,并注意時效性,一般是兩年,自知道或應當知道權利被侵害之日起算。 3.追償損失可先由林場或林政部門與當事人協商,法務部門、財務、總務等相關部門配合,若不能及時取得賠償或補償,經公司總經理核準以訴訟方式索賠的,由法務部門處理。 (六)結案 1、經主管機關處理過的侵權人已經得到處理、我方損失得到全額賠償或持續維護林漿紙基地之利益已達成的案件或已超過訴訟時效、其他長期積壓無法處理的案件,由案件承辦部門或人員制作《結案報告表》(附件2),并依報批程序逐級呈報到公司總經理決定是否結案。 2、結案后應通知公司相關部門,對原有事實及現場狀況需做變更的,由相關部門及時調整,同時通知林場執行處理結果。 3、結案后,整個案件材料應完整歸檔,作為該林班檔案的組成部分,交公司檔案部門保管。 七 各異常案件承辦部門應定期將待辦案件(純粹技術性的異常案件除外,如病蟲害、風害等)匯總報法務部門,法務部門根據案件的性質、進度及難點提出合理化意見和建議,推進案件的解決進度。對于需要訴訟或即將超過訴訟期限的案件,及時進入訴訟程序,或采取有效措施,使訴訟時效得以順延。 八 公司逐步設立異常案件獎懲辦法,以促進異常案件及時有效處理。 凡違反本辦法規定,對異常案件負有提報、處理、配合、組織、領導、協調、支援等責任的責任人怠于履行職責,給公司造成較大損失或其他損害的,按照公司有關規定予以處分或依法追究。 九 本辦法經權責主管簽署生效。 事業區負責人 總(副)經理 審核 擬稿第二篇:C# System命名空間簡介
第三篇:使用DFS創建命名空間
第四篇:分布式文件系統命名空間解析
第五篇:異常案件處理辦法