国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

深度解析C++異常處理機(jī)制:分類、處理方式、常見錯(cuò)誤及11新增功能

這篇具有很好參考價(jià)值的文章主要介紹了深度解析C++異常處理機(jī)制:分類、處理方式、常見錯(cuò)誤及11新增功能。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

一、基礎(chǔ)

1. 異常的概念

異常是程序在運(yùn)行過程中出現(xiàn)非正常情況的處理機(jī)制。當(dāng)出現(xiàn)異常時(shí)程序會(huì)停止運(yùn)行并調(diào)用異常處理程序。

2. 異常的分類

異??梢苑譃閮?nèi)置異常和自定義異常

2.1 內(nèi)置異常

C++ 標(biāo)準(zhǔn)庫(kù)提供了許多預(yù)定義的異常類,稱為內(nèi)置異常,包括以下幾種:

  • std::exception:所有標(biāo)準(zhǔn)異常類的基類。
  • std::logic_error:表示程序邏輯錯(cuò)誤。
  • std::runtime_error:表示運(yùn)行時(shí)錯(cuò)誤。

2.2 自定義異常

除了使用內(nèi)置異常,我們還可以創(chuàng)建自定義異常類來處理特定錯(cuò)誤。自定義異常類可以繼承自內(nèi)置異常類以實(shí)現(xiàn)異常的精細(xì)控制。

3. 異常的處理方式

C++ 提供了以下幾種處理異常的方式:

3.1 try-catch 語句

try {
  // 可能會(huì)拋出異常的代碼塊
} catch (exception1_type exception1_var) {
  // 處理異常類型1
} catch (exception2_type exception2_var) {
  // 處理異常類型2
}

使用 try 代碼塊來包含可能拋出異常的代碼,緊跟 catch 塊來處理捕獲到的異常。當(dāng)拋出異常后,程序會(huì)自動(dòng)匹配 catch 塊中與對(duì)應(yīng)異常相同類型的代碼塊執(zhí)行,保證程序正常執(zhí)行。

3.2 throw 語句

throw exception_object;

使用 throw 語句拋出一個(gè)異常對(duì)象,使程序進(jìn)入異常處理模式。 exception_object 可以是基本類型或?qū)ο螅踔量梢允亲远x類型的實(shí)例。

3.3 noexcept 修飾符

void function_name() noexcept {
  // 不會(huì)拋出異常的函數(shù)
}

noexcept 修飾符指示函數(shù)不拋出異常。使用 noexcept 可以優(yōu)化程序性能。當(dāng)程序遇到一個(gè)沒有 noexcept 修飾符的函數(shù),會(huì)假設(shè)這個(gè)函數(shù)可能拋出異常,導(dǎo)致額外的代碼執(zhí)行。

3.4 finally 語句塊

try{
  // 可能拋出異常的代碼塊
} catch(...) {
  // 處理異常
} finally {
  // 無論有無異常都執(zhí)行
}

finally 語句在 try-catch 語句的末尾執(zhí)行,無論異常是否拋出。通常用于釋放資源等程序收尾工作。

綜上所述異常處理是程序設(shè)計(jì)中重要而必不可少的一部分。了解常見的異常處理方式,可以讓我們更加高效地處理程序中的錯(cuò)誤,并確保程序的正常運(yùn)行。

二、 異常處理機(jī)制

C++中的異常處理機(jī)制用于處理程序運(yùn)行過程中的異常情況。異常可以是程序中的一種錯(cuò)誤或者突發(fā)事件,可能會(huì)導(dǎo)致程序崩潰,但是正常情況下我們希望程序可以平穩(wěn)地運(yùn)行下去,去處理這些異常情況。在這樣的情況下, C++的異常處理機(jī)制發(fā)揮了巨大的作用。

1 try-catch 語句塊

try-catch 是處理 C++ 異常的關(guān)鍵工具。它的主要作用是將異常處理分離出代碼,將異常在運(yùn)行時(shí)捕獲并處理。

try {
  // 可能引發(fā)異常的代碼塊
} catch (Type1 arg1) {
  // 處理Type1類型的異常
} catch (Type2 arg2) {
  // 處理Type2類型的異常
} catch (Type3 arg3) {
  // 處理Type3類型的異常
}

當(dāng)一個(gè)異常被拋出的時(shí)候(通常是使用 throw 語句),與拋出異常的類型相匹配的 catch 塊會(huì)被調(diào)用,它會(huì)處理異常并從這個(gè)異常中恢復(fù)程序執(zhí)行。

2 異常處理流程

異常處理的整個(gè)過程是一種順序執(zhí)行模型,以下是它的基本流程:

  1. 程序執(zhí)行到可能拋出異常的代碼時(shí),這段代碼必須嵌入到 try 塊中。
  2. 如果在 try 塊中的代碼引發(fā)了異常,程序會(huì)跳轉(zhuǎn)到與拋出異常類型匹配的 catch 塊中,catch 塊負(fù)責(zé)處理異常。
  3. 最后程序會(huì)從 catch 塊中退出,向下執(zhí)行任何后續(xù)代碼。

簡(jiǎn)單來說,我們可以將異常處理機(jī)制的處理過程看作是程序運(yùn)行時(shí)一條流程線,它沿著 try-catch 塊執(zhí)行,遇到異常時(shí)跳轉(zhuǎn) catch 塊那里處理異常,最后退出 catch 塊。

3 標(biāo)準(zhǔn)異常類

C++ 標(biāo)準(zhǔn)庫(kù)中定義了一些異常類,這些異常類是所有 C++ 應(yīng)用程序都可以使用的。由于這些異常類是預(yù)定義的,因此它們都是放在 std 命名空間之下。

C++ 標(biāo)準(zhǔn)庫(kù)提供的異常類:

  1. std::exception —— 所有標(biāo)準(zhǔn)異常類的基類。
  2. std::bad_alloc —— 在申請(qǐng)內(nèi)存失敗時(shí)拋出。
  3. std::bad_cast —— 將一個(gè)指向派生類的基類指針強(qiáng)制轉(zhuǎn)換為派生類指針時(shí),如果類不是目標(biāo)類型,則拋出。
  4. std::ios_base::failure —— I/O 操作失敗時(shí)拋出。
  5. std::out_of_range —— 數(shù)組訪問越界時(shí)拋出。
  6. std::invalid_argument —— 提供無效參數(shù)時(shí)拋出。
  7. std::length_error —— 嘗試創(chuàng)建一個(gè)超出可分配內(nèi)存大小的vector、string等時(shí)發(fā)生。
  8. std::logic_error —— 人為 bug,如出現(xiàn)未在程序中考慮到的條件等,通常還有一些 derived class 總結(jié)不同的情況(此類異??梢栽诰幾g環(huán)境中靜態(tài)檢查出來)。
  9. std::runtime_error —— 運(yùn)行時(shí)錯(cuò)誤,一般情況下是在單個(gè)文件運(yùn)行時(shí)出錯(cuò)。(常常由文件、網(wǎng)絡(luò)等外部原因引起)

以上這些異常類是為了解決常見的情況而設(shè)計(jì)的,它們能夠支持很多常見的內(nèi)部錯(cuò)誤,如果我們想要精細(xì)控制異常,我們還可以創(chuàng)建自定義異常。

通過使用異常處理機(jī)制,程序員可以保證程序的正常運(yùn)行,在發(fā)生異常時(shí)捕獲并處理它們,從而防止程序崩潰。同時(shí)使用標(biāo)準(zhǔn)異常類,也可以避免一些常見的錯(cuò)誤和異常。

三、 拋出異常

在C++中可以使用異常處理機(jī)制來處理程序中的異常情況。當(dāng)程序出現(xiàn)錯(cuò)誤或突發(fā)事件時(shí),異常處理機(jī)制可以讓程序正常運(yùn)行下去,而不會(huì)導(dǎo)致程序崩潰。那么如何拋出異常呢,我們一起來看看

1 throw語句

使用throw語句可以拋出異常,throw語句必須跟上一個(gè)表達(dá)式該表達(dá)式是拋出的異常對(duì)象,如下所示:

throw someException; // 拋出異常

我們可以用任何類型的值做為異常對(duì)象,不過通常我們會(huì)把異常對(duì)象設(shè)置為標(biāo)準(zhǔn)庫(kù)的異常類之一

2 異常類型

異常類型是某種類型的值,它可以用于標(biāo)識(shí)需要通知程序時(shí)發(fā)生了什么錯(cuò)誤。異常類型可以是任意類型,但為了能夠與 catch 塊中的異常參數(shù)類型匹配,通常使用異常類的對(duì)象或指針。

下面是一個(gè)簡(jiǎn)單的示例,在函數(shù)中拋出一個(gè)異常:

// 聲明一個(gè)自定義的異常類
class MyException : public exception {
public:
    // 重寫 what() 函數(shù),返回異常信息
    const char* what() const noexcept override {
        return "MyException occurred";
    }
};

void myFunction() {
    throw MyException(); // 拋出自定義異常
}

在拋出異常時(shí)可以使用任何類型的值,但是為了能夠被 catch 塊所匹配,一般使用異常類的對(duì)象或指針,也可以自定義異常類

3 異常傳遞

如果在函數(shù)中拋出了異常,那么異常會(huì)被拋到調(diào)用該函數(shù)的代碼中。如果這個(gè)函數(shù)也沒有捕獲這個(gè)異常,那么異常就會(huì)繼續(xù)傳遞到更高的層次,直到被捕獲為止。

下面是一個(gè)示例代碼,展示了異常是如何傳遞的:

void functionC() {
    cout << "Starting function C" << endl;
    throw MyException(); // 拋出自定義異常
    cout << "Ending function C" << endl;
}

void functionB() {
    cout << "Starting function B" << endl;
    functionC(); // 調(diào)用functionC
    cout << "Ending function B" << endl;
}

void functionA() {
    cout << "Starting function A" << endl;
    try {
        functionB(); // 調(diào)用functionB
    } catch (const exception& e) {
        cerr << e.what() << endl; // 捕獲并處理異常
    }
    cout << "Ending function A" << endl;
}

int main() {
    cout << "Starting main function" << endl;
    functionA(); // 調(diào)用functionA
    cout << "Ending main function" << endl;
    return 0;
}

輸出結(jié)果為:

Starting main function
Starting function A
Starting function B
Starting function C
MyException occurred
Ending function A
Ending main function

首先main函數(shù)調(diào)用 functionA。functionA 內(nèi)部調(diào)用 functionB,并且包含一個(gè) try 塊,用來捕獲異常。functionB 內(nèi)部調(diào)用 functionC并拋出了一個(gè)異常,這個(gè)異常傳遞到了 functionA 中被 catch 塊捕獲并處理。

這里需要注意的是一旦拋出了一個(gè)異常,函數(shù)就會(huì)終止。因此functionC 中的 cout 語句不會(huì)被執(zhí)行到。

總結(jié)起來異常處理機(jī)制是 C++ 中重要的一部分,它可以幫助程序處理錯(cuò)誤和突發(fā)事件,并保證程序的正常運(yùn)行。在拋出異常時(shí)需要考慮使用什么類型的異常對(duì)象,并養(yǎng)成良好的習(xí)慣在適當(dāng)?shù)牡胤讲东@異常。

四、 捕獲異常

在C++中捕獲異常是指捕獲并處理由 throw 語句拋出的異常。在異常處理機(jī)制中,try 塊用于捕獲異常并處理它們,而 catch 塊則用于處理 try 塊中拋出的異常。下面我們來看看如何使用 catch 塊來捕獲和處理異常

1 catch語句

catch 塊用于捕獲和處理由 try 塊拋出的異常。catch 塊必須跟上一個(gè)括號(hào),括號(hào)中是一個(gè)參數(shù),它是 catch 塊的異常參數(shù),用來接收拋出的異常對(duì)象
如下所示:

try {
    // 可能會(huì)發(fā)生異常的代碼
} catch (exceptionType& e) {
    // 處理異常的代碼
}

這里的 exceptionType 是異常類型的名字,使用與 throw 語句中拋出的一致的類型或基類類型。&e 表示將異常對(duì)象的引用傳遞給 catch 塊中的代碼,從而使得 catch 塊能夠訪問并處理該異常對(duì)象。需要注意的是,&e 表示對(duì)異常對(duì)象的只讀訪問不能對(duì)傳遞過來的異常對(duì)象進(jìn)行修改。

我們可以使用多個(gè) catch 塊來處理不同類型的異常,這樣可以將異常處理代碼與常規(guī)代碼分離,更好地管理程序錯(cuò)誤和異常。下面我們來看看多個(gè) catch 塊的順序和匹配規(guī)則

2 多個(gè)catch語句的順序與匹配規(guī)則

當(dāng)由 try 塊拋出一個(gè)異常時(shí),程序會(huì)按照由上到下的順序遍歷 catch 塊,直到找到一個(gè)與拋出的異常匹配的 catch 塊為止。這里的匹配指的是異常參數(shù)類型與拋出的異常對(duì)象類型一致,或者是該異常的基類類型。如果找不到合適的 catch 塊,則程序?qū)惓鬟f到更高層次的代碼中。

需要注意的是如果有多個(gè) catch 塊可以匹配拋出的異常,C++ 編譯器將使用第一個(gè)合適的 catch 塊進(jìn)行處理,而不是使用最具體的 catch 塊。因此在編寫多個(gè) catch 塊時(shí),應(yīng)該將最具體的 catch 塊放在最前面

下面是一個(gè)示例,它展示了多個(gè) catch 塊的順序和匹配規(guī)則:

try {
    // 可能會(huì)發(fā)生異常的代碼
} catch (const Exception1& e) {
    // 處理異常1的代碼
} catch (const Exception2& e) {
    // 處理異常2的代碼
} catch (const Exception3& e) {
    // 處理異常3的代碼
} catch (const exception& e) {
    // 處理其他異常的代碼
}

在這個(gè)示例中當(dāng)由 try 塊拋出 Exception1 類型的異常時(shí),程序會(huì)執(zhí)行第一個(gè) catch 塊。當(dāng)拋出 Exception2 類型的異常時(shí),程序會(huì)執(zhí)行第二個(gè) catch 塊。當(dāng)拋出 Exception3 類型的異常時(shí),程序會(huì)執(zhí)行第三個(gè) catch 塊。當(dāng)拋出其他異常時(shí)程序會(huì)執(zhí)行最后一個(gè) catch 塊。

3 異常處理機(jī)制的使用示例

下面是一個(gè)簡(jiǎn)單的示例,它展示了異常處理機(jī)制的使用。我們自定義一個(gè)異常類 DivideByZeroException用于拋出在除法運(yùn)算中除數(shù)為零的異常。在該程序中,我們使用 try 塊和 catch 塊來捕獲和處理異常,并且為了更好地管理程序錯(cuò)誤和異常,將業(yè)務(wù)邏輯和異常處理代碼分離開來。

#include <iostream>
#include <exception>
using namespace std;

// 自定義一個(gè)異常類
class DivideByZeroException : public exception {
public:
    // 重寫 what() 函數(shù),返回異常信息
    const char* what() const noexcept override {
        return "Attempt to divide by zero";
    }
};

// 除法函數(shù),在該函數(shù)中可能會(huì)拋出一個(gè) DivideByZeroException 異常
double divide(double a, double b) {
    if (b == 0) {
        throw DivideByZeroException();
    }
    return a / b;
}

int main() {
    double a = 42, b = 0, result;
    try {
        result = divide(a, b);
        cout << "Result is: " << result << endl;
    } catch (const DivideByZeroException& e) {
        cerr << "Exception caught: " << e.what() << endl;
    }
    cout << "Program continues to run" << endl;
    return 0;
}

在該示例中定義了一個(gè) 除法函數(shù) divide,該函數(shù)接收兩個(gè) double 類型的參數(shù) a 和 b,如果除數(shù) b 為零,則拋出一個(gè) DivideByZeroException 異常。在程序中我們?cè)?try 塊中調(diào)用 divide 函數(shù),并通過 catch 塊來捕獲并處理拋出的異常。我們?cè)?catch 塊中打印出異常信息并繼續(xù)執(zhí)行程序。最后輸出的結(jié)果應(yīng)該是:

Exception caught: Attempt to divide by zero
Program continues to run

以上就是關(guān)于 catch 塊的使用和異常處理機(jī)制的一個(gè)簡(jiǎn)單示例,希望可以幫助您更好地掌握 C++ 中的異常處理機(jī)制。

五、 C++11 新增異常功能

在C++11中增加了一些異常的功能,讓我們來看看

1 noexcept操作符

noexcept是一個(gè)C++11新增的操作符,它用于指明一個(gè)函數(shù)是否可能拋出異常。當(dāng)一個(gè)函數(shù)有可能拋出異常時(shí),我們可以在其聲明或定義前使用 noexcept 關(guān)鍵字告知編譯器這一信息。這個(gè)操作符的作用是幫助編譯器進(jìn)行優(yōu)化,提高代碼的效率。

一個(gè)使用 noexcept 的函數(shù)可以被認(rèn)為是“拋出異常不影響程序正確性”的,這意味著該函數(shù)不會(huì)拋出異常,或者拋出異常后程序可以優(yōu)雅地進(jìn)行終止。

下面是一個(gè)使用 noexcept 關(guān)鍵字的示例:

#include <iostream>
using namespace std;

void func1() noexcept {
    cout << "func1: No exceptions here!" << endl;
}

void func2() {
    throw runtime_error("Exception in func2");
}

int main() {
    cout << boolalpha;
    cout << "func1 is noexcept: " << noexcept(func1()) << endl; // 輸出 true
    cout << "func2 is noexcept: " << noexcept(func2()) << endl; // 輸出 false
}

在這個(gè)示例中定義了兩個(gè)函數(shù) func1 和 func2,其中 func1 使用了 noexcept,并且沒有拋出任何異常。而 func2 則可能會(huì)拋出一個(gè) runtime_error 異常。在主函數(shù)中,我們使用 noexcept 來檢查 func1 和 func2 是否使用了 noexcept 進(jìn)行聲明或定義,從而判斷它們是否可能會(huì)拋出異常。

需要注意的是noexcept 操作符只能用于函數(shù)聲明或定義的末尾,這個(gè)末尾必須是分號(hào)或花括號(hào)。對(duì)于類的成員函數(shù),可以在函數(shù)名后的括號(hào)內(nèi)使用它,如下所示:

class MyClass {
public:
    void func1() noexcept;
    void func2() noexcept(true) { // 或者把true換成false
        throw runtime_error("Exception in func2");
    }
};

在類的成員函數(shù)聲明或定義中也可以使用 noexcept 進(jìn)行限定,但有一個(gè)細(xì)微的差別,可以將其放在括號(hào)內(nèi)來表示類作為一個(gè)新環(huán)境。括號(hào)內(nèi)的布爾值指定了該函數(shù)是否可能拋出異常。

2 異常列表(function try-block)

在 C++11 中還新增了異常列表,也叫函數(shù) try 塊。這個(gè)功能允許我們?cè)诤瘮?shù)定義中捕獲異常并處理,與在函數(shù)體中進(jìn)行異常處理不同,這讓我們可以將所有異常處理代碼放在同一個(gè)位置,提高代碼的可讀性和可維護(hù)性。

在函數(shù)體開始之前,在函數(shù)參數(shù)列表后立即使用 try 關(guān)鍵字并緊跟著花括號(hào),在花括號(hào)中包含函數(shù)體,需要同時(shí)聲明和捕獲異常。需要注意的是,如果一個(gè)函數(shù)既有函數(shù) try 塊,又有普通的 try-catch 塊,它們的處理順序是不一樣的,函數(shù) try 塊中的異常處理將先于普通的 try-catch 塊執(zhí)行。

下面是一個(gè)函數(shù) try 塊的示例代碼:

#include <iostream>
#include <stdexcept>
using namespace std;

class MyClass {
public:
    MyClass() : num(42) {
        cout << "Constructing MyClass" << endl;
    }

    ~MyClass() noexcept(false) {
        cout << "Destructing MyClass" << endl;
        throw runtime_error("Exception in destructor");
    }

    void DoSomething() noexcept(false) {
        cout << "Doing something" << endl;
        throw runtime_error("Exception in DoSomething");
    }

private:
    int num;
};

void f(MyClass& mc) try {
    mc.DoSomething();
} catch (const exception& e) {
    cerr << "Caught exception in f(): " << e.what() << endl;
}

int main() {
    MyClass mc;
    f(mc);
    return 0;
}

在這個(gè)示例中定義了一個(gè) MyClass 類,該類包含了一個(gè)有副作用的默認(rèn)構(gòu)造函數(shù)和一個(gè)有副作用的析構(gòu)函數(shù),它們都可能會(huì)拋出異常。MyClass 類還包含一個(gè)成員函數(shù) DoSomething,這個(gè)函數(shù)也可能會(huì)拋出異常。我們使用了函數(shù) try 塊來定義了一個(gè)函數(shù) f,該函數(shù)調(diào)用了成員函數(shù) DoSomething,并在函數(shù)名后面使用了 try 來聲明和捕獲異常。在 catch 塊中打印出異常信息。

在主函數(shù)中創(chuàng)建了一個(gè) MyClass 對(duì)象,然后調(diào)用函數(shù) f 來演示函數(shù) try 塊的使用。

以上就是 C++11 中新增的兩個(gè)異常功能:noexcept 操作符和異常列表(function try-block)。這些新功能使我們可以更好地處理異常,寫出更健壯、高效的代碼。

六、常見錯(cuò)誤和異常處理

在編寫代碼時(shí),我們難免會(huì)遇到一些錯(cuò)誤與異常。這些錯(cuò)誤與異??赡軙?huì)導(dǎo)致我們的程序崩潰或者出現(xiàn)一些意想不到的行為。因此在編寫代碼的過程中,我們應(yīng)該注意一些常見的錯(cuò)誤和異常,以便及時(shí)解決它們或者避免它們的發(fā)生。

1 空指針異常

指針是我們編程過程中經(jīng)常使用的一個(gè)概念,空指針異常指當(dāng)我們使用一個(gè)空指針時(shí),會(huì)出現(xiàn)意想不到的行為或意外的程序崩潰。

下面是一個(gè)關(guān)于空指針異常的代碼示例:

int* p = nullptr; // 定義一個(gè)空指針
int a = *p; // 這里會(huì)發(fā)生空指針異常

在代碼示例中定義了一個(gè)空指針 p,然后試圖去訪問 p 指向的內(nèi)存空間中的值,并將其賦值給變量 a,這里就會(huì)發(fā)生空指針異常。

在C++ 中我們可以通過以下方式來避免空指針異常的發(fā)生:

  1. 在使用指針之前要進(jìn)行判斷,確保指針不為空。
  2. 在給指針分配內(nèi)存空間時(shí),要使用 new 操作符,并進(jìn)行異常處理。

2 內(nèi)存泄漏異常

內(nèi)存泄漏指程序在分配了內(nèi)存空間后,沒有合適的方式來釋放它。內(nèi)存泄漏會(huì)導(dǎo)致程序內(nèi)存空間的消耗過大,從而影響程序性能。

下面是一個(gè)內(nèi)存泄漏的代碼示例:

int* p = new int; // 分配了一個(gè)動(dòng)態(tài)內(nèi)存空間
p = nullptr; // 將指針指向空

在代碼示例中通過 new 操作符動(dòng)態(tài)地分配了一段內(nèi)存空間,但是在之后將指針置為空時(shí),我們并沒有使用 delete 來釋放所分配的內(nèi)存空間,從而導(dǎo)致了內(nèi)存泄漏。

在C++ 中應(yīng)該避免內(nèi)存泄漏的發(fā)生。一種常見的做法是,在分配內(nèi)存空間時(shí)使用智能指針(smart pointer),它們會(huì)在指針不再需要時(shí)自動(dòng)釋放所分配的內(nèi)存空間。

3 數(shù)組越界異常

數(shù)組越界是指訪問數(shù)組的時(shí)候,訪問一個(gè)超出了數(shù)組范圍的索引,其結(jié)果是未定義的行為。訪問越界的錯(cuò)誤有時(shí)可能看起來沒有任何影響,但是在某些情況下,它們可能會(huì)對(duì)程序的運(yùn)行時(shí)行為產(chǎn)生嚴(yán)重的影響。

下面是一個(gè)數(shù)組越界的代碼示例:

int arr[5] = {1, 2, 3, 4, 5};
int n = 6;
int a = arr[n]; // 這里會(huì)發(fā)生數(shù)組越界

在代碼示例中定義了一個(gè)長(zhǎng)度為 5 的數(shù)組 arr,然后試圖訪問數(shù)組中不存在的索引 n,這里就會(huì)發(fā)生數(shù)組越界異常。

在C++ 中我們可以通過以下方式來避免數(shù)組越界異常的發(fā)生:

  1. 在訪問數(shù)組元素時(shí),要確保訪問的索引在有效范圍內(nèi)。
  2. 在使用數(shù)組之前要進(jìn)行初始化。

4 死鎖異常

死鎖是指兩個(gè)或多個(gè)進(jìn)程(線程)相互等待對(duì)方釋放共享資源,從而導(dǎo)致進(jìn)程(線程)阻塞的情況。死鎖是多線程編程中比較常見的一個(gè)問題,一旦發(fā)生,會(huì)導(dǎo)致程序的掛起,從而影響程序的性能。

下面是一個(gè)死鎖的代碼示例:

#include <mutex>
#include <thread>

void func(std::mutex& m1, std::mutex& m2) {
    m1.lock();
    m2.lock(); // 這里會(huì)導(dǎo)致死鎖
    // ...
    m2.unlock();
    m1.unlock();
}

int main() {
    std::mutex m1, m2;
    std::thread t1(func, std::ref(m1), std::ref(m2));
    std::thread t2(func, std::ref(m2), std::ref(m1));
    t1.join();
    t2.join();
    return 0;
}

在代碼示例中定義了兩個(gè)線程 t1t2,它們分別執(zhí)行函數(shù) func。在函數(shù)中,我們使用了兩個(gè)互斥量 m1m2 來保證在訪問共享資源前線程的同步,但是在執(zhí)行線程 t1t2 的時(shí)候,如果它們同時(shí)試圖獲取 m1m2 的互斥鎖,就會(huì)導(dǎo)致死鎖異常的發(fā)生。

在 C++ 中可以通過以下方式來避免死鎖異常的發(fā)生:文章來源地址http://www.zghlxwxcb.cn/news/detail-799537.html

  1. 避免使用多個(gè)互斥量進(jìn)行同步。
  2. 在使用互斥量時(shí),謹(jǐn)慎使用 lock 和 unlock
  3. 使用 RAII 實(shí)現(xiàn)自動(dòng)加鎖和解鎖,在 C++11 中,我們可以使用 std::lock_guardstd::unique_lock 來實(shí)現(xiàn)在構(gòu)造函數(shù)中加鎖,在析構(gòu)函數(shù)中解鎖的操作

到了這里,關(guān)于深度解析C++異常處理機(jī)制:分類、處理方式、常見錯(cuò)誤及11新增功能的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 解析Python爬蟲常見異常及處理方法

    解析Python爬蟲常見異常及處理方法

    作為專業(yè)爬蟲程序猿長(zhǎng)期混跡于爬蟲ip解決方案中,我們經(jīng)常會(huì)遇到各種各樣的異常情況。在爬蟲開發(fā)過程中,處理這些異常是不可或缺的一部分。本文將為大家總結(jié)常見的Python爬蟲異常,并分享相應(yīng)的處理方法,幫助你避免絆倒在爬蟲之路上。 一、網(wǎng)絡(luò)連接異常 1、 Timeou

    2024年02月12日
    瀏覽(18)
  • Python 異常處理深度解析:掌握健壯代碼的關(guān)鍵

    Python 異常處理深度解析:掌握健壯代碼的關(guān)鍵

    有效管理和處理異常是構(gòu)建健壯、可靠和用戶友好應(yīng)用程序的基石。異常處理不僅有助于防止程序意外崩潰,還能為用戶提供更清晰的錯(cuò)誤信息,幫助開發(fā)者診斷問題。本文將全面介紹 Python 中的異常處理機(jī)制,從基本的 try-except 結(jié)構(gòu)到高級(jí)的異常管理技術(shù),包括異常鏈和自

    2024年04月26日
    瀏覽(23)
  • 【C++高階(七)】C++異常處理的方式

    【C++高階(七)】C++異常處理的方式

    ??博主CSDN主頁(yè):杭電碼農(nóng)-NEO?? ? ?專欄分類:C++從入門到精通? ? ??代碼倉(cāng)庫(kù):NEO的學(xué)習(xí)日記?? ? ??關(guān)注我??帶你學(xué)習(xí)C++ ? ???? C++有一套獨(dú)立的異常處理機(jī)制, 相信大家一定聽說過try,catch這兩 個(gè)詞,今天就來做詳細(xì)的介紹 本章重點(diǎn): 本篇文章著重講解C++異常處理的方

    2024年02月04日
    瀏覽(20)
  • java異常處理機(jī)制(二)之異常處理與捕獲

    java異常處理機(jī)制(二)之異常處理與捕獲

    1 Error(錯(cuò)誤): 是指程序無法處理的錯(cuò)誤,表示運(yùn)行應(yīng)用程序時(shí)比較嚴(yán)重的問題。大多數(shù)錯(cuò)誤與代碼編寫者執(zhí)行的操作無關(guān),而表示代碼運(yùn)行時(shí)JVM(Java 虛擬機(jī))出現(xiàn)的問題。 2 異常(Exception): 是指在程序執(zhí)行時(shí)由于程序處理邏輯上的錯(cuò)誤而導(dǎo)致程序中斷的一種指令流。通俗的

    2024年02月05日
    瀏覽(21)
  • 爬蟲異常處理:異常捕獲與容錯(cuò)機(jī)制設(shè)計(jì)

    爬蟲異常處理:異常捕獲與容錯(cuò)機(jī)制設(shè)計(jì)

    作為一名專業(yè)的爬蟲程序員,每天使用爬蟲IP面對(duì)各種異常情況是我們每天都會(huì)遇到的事情。 在爬取數(shù)據(jù)的過程中,我們經(jīng)常會(huì)遇到網(wǎng)絡(luò)錯(cuò)誤、頁(yè)面結(jié)構(gòu)變化、被反爬蟲機(jī)制攔截等問題。在這篇文章中,我將和大家分享一些關(guān)于如何處理爬蟲異常情況的經(jīng)驗(yàn)和技巧。通過異常

    2024年02月11日
    瀏覽(17)
  • 【C++】C++異常機(jī)制

    【C++】C++異常機(jī)制

    終止程序,如 assert 直接斷言報(bào)錯(cuò),缺陷:非常麻煩,如果發(fā)生內(nèi)存錯(cuò)誤,除零錯(cuò)誤會(huì)立即終止程序 返回錯(cuò)誤碼。缺陷:需要程序員自己去查渣哦對(duì)應(yīng)的錯(cuò)誤,如系統(tǒng)庫(kù)的接口函數(shù)都是通過錯(cuò)誤碼放到errno中,需要程序員自己去讀區(qū)錯(cuò)誤碼進(jìn)行錯(cuò)誤處理 C標(biāo)準(zhǔn)庫(kù)中的setjmp和lo

    2024年02月16日
    瀏覽(13)
  • Spring 的異常處理機(jī)制

    ? 在Spring中,異常處理是一個(gè)非常重要的方面,用于捕獲和處理應(yīng)用程序中可能出現(xiàn)的異常情況。Spring提供了多種方式來處理異常。 ? 使用Spring的異常處理機(jī)制主要有以下優(yōu)點(diǎn): ? **統(tǒng)一的異常處理:**通過全局異常處理器,可以實(shí)現(xiàn)一致的異常處理邏輯,而不需要在每個(gè)

    2024年02月11日
    瀏覽(21)
  • 【JAVA 異常處理機(jī)制】

    【JAVA 異常處理機(jī)制】

    在Java編程中,異常處理是一種重要的機(jī)制,用于處理程序運(yùn)行時(shí)可能出現(xiàn)的錯(cuò)誤和異常情況。異常處理機(jī)制可以幫助開發(fā)者優(yōu)雅地處理異常,提高程序的健壯性和可靠性。 提示:以下是本篇文章正文內(nèi)容,下面案例可供參考 java中所有錯(cuò)誤的超類為:Throwable。其下有兩個(gè)子類

    2024年02月11日
    瀏覽(21)
  • SpringBoot 異常處理機(jī)制

    SpringBoot 異常處理機(jī)制

    SpringBoot中異常處理的流程圖 在SpringBoot項(xiàng)目中,如果業(yè)務(wù)邏輯發(fā)生了異常,則首先看發(fā)生異常的類中有沒有@ExceptionHandle能處理,如果能,則執(zhí)行方法進(jìn)行處理,如果沒有,則去找全局的@ControllerAdvice注解,進(jìn)行異常處理,如果還是不能處理,則繼續(xù)看SpringMVC的異常處理機(jī)制能

    2024年02月16日
    瀏覽(24)
  • Java 異常處理機(jī)制(全)

    Java 異常處理機(jī)制(全)

    1.1? 異常定義 ??? (1)在使用計(jì)算機(jī)語言進(jìn)行項(xiàng)目開發(fā)的過程中,即使程序員把代碼寫得盡善盡美,在系統(tǒng)的運(yùn)行過程中仍然會(huì)遇到一些問題,因?yàn)楹芏鄦栴}不是靠代碼能夠避免的,比如:客戶輸入數(shù)據(jù)的格式,讀取文件是否存在,網(wǎng)絡(luò)是否始終保持通暢等等。 ??? (2)

    2024年02月08日
    瀏覽(24)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包