C++初登門檻

多態

一、概念

多態是指不同對象對同一消息產生不同響應的行為。例如,藍牙、4G、Wi-Fi 對“發送數據”指令有不同的具體實現。

二、核心理解
  • 本質:通過基類指針或引用操作子類對象,實現運行時動態綁定

  • 表現形式

    • 接口統一:基類定義通用接口(如?virtual void TransmitData())。

    • 實現多樣:子類重寫接口,提供具體功能(如藍牙發送數據的具體邏輯)。

三、分類與對比

類型靜態多態(早綁定)動態多態(晚綁定)
實現方式函數重載、模板虛函數(virtual
綁定時機編譯期確定調用函數運行時根據對象類型確定調用函數
靈活性低(依賴編譯時類型)高(支持運行時多態)
四、作用與意義
  1. 通用性:將不同子類對象視為基類對象,編寫統一代碼。

    SendData* devices[] = {new Bluetooth(), new A4G(), new WiFi()};  
    for (auto device : devices) {  device->TransmitData();  // 統一接口,不同實現  
    } 
  2. 擴展性:新增子類無需修改現有代碼(如新增 ZigBee 模塊)。

  3. 解耦:分離接口與實現,降低代碼依賴性。

五、實現前提條件
  1. 繼承關系:必須存在基類與子類的繼承結構。

  2. 虛函數重寫:基類方法用?virtual?聲明,子類重寫該方法。

  3. 基類引用/指針指向子類對象:通過基類操作實際子類對象。

六、實現步驟(以物聯網設備為例)
  1. 定義基類虛函數

    class SendData {  
    public:  virtual void TransmitData() = 0;  // 純虛函數  virtual ~SendData() = default;    // 虛析構函數  
    }; 
  2. 子類繼承并重寫虛函數

    class Bluetooth : public SendData {  
    public:  void TransmitData() override {  cout << "藍牙發送數據..." << endl;  }  
    }; 
  3. 使用基類指針操作子類對象

    int main() {  SendData* device = new Bluetooth();  device->TransmitData();  // 動態調用 Bluetooth 的實現  delete device;  return 0;  
    }  
七、應用場景示例(物聯網設備數據傳輸)
  • 需求:統一管理藍牙、4G、Wi-Fi 的數據傳輸接口。

  • 設計

    • 基類?SendData?定義虛函數?TransmitData()

    • 子類?BluetoothA4GWiFi?分別實現具體傳輸邏輯。

    • 客戶端通過基類指針調用接口,無需關心具體設備類型。

八、注意事項
  1. 虛析構函數:基類必須聲明虛析構函數,確保正確釋放子類資源。

  2. 避免切片問題:使用指針或引用傳遞對象,而非值傳遞。

  3. 純虛函數:若基類僅定義接口,可聲明為純虛函數(= 0),使基類成為抽象類。

代碼示例:
//4G通訊
#include <iostream>
#include "send_data.h"
#include <cstring>
#ifndef  __A4G__HEAD__
#define __A4G__HEAD__
using namespace std;
class A4G:public Send_data
{
private:char* data;
public:A4G(const char* data);void Transmit_data();virtual ~A4G();
};
//構造函數
A4G::A4G( const char* data)
{cout << "構造函數" << endl;this->data = new char[strlen(data) + 1]; // 分配內存strcpy(this->data, data); // 復制內容
}void A4G::Transmit_data(){cout << "用4G發送數據:" << this->data << endl;
}A4G::~A4G()
{cout << "~A4G" << endl;
}#endif  
//藍牙通訊
#include <iostream>
#include "send_data.h"
#include <cstring>
#ifndef  __Blue_tooth__HEAD__
#define __Blue_tooth__HEAD__
using namespace std;
class Blue_tooth:public Send_data
{
private:char* data;
public:Blue_tooth(const char* data);void Transmit_data();virtual ~Blue_tooth();
};
//構造函數
Blue_tooth::Blue_tooth(const char* data)
{cout << "構造函數" << endl;this->data = new char[strlen(data) + 1]; // 分配內存strcpy(this->data, data); // 復制內容
}void Blue_tooth::Transmit_data(){cout << "用藍牙發送數據:" << this->data << endl;
}Blue_tooth::~Blue_tooth()
{cout << "~Blue_tooth" << endl;delete []data;
}#endif // DEBUG
//WiFi通訊
#include <iostream>
#include "send_data.h"
#ifndef  __Wifi__HEAD__
#define __Wifi__HEAD__
using namespace std;
class Wifi:public Send_data
{
private:char* data;
public:Wifi(const char* data);void Transmit_data();virtual ~Wifi();
};
//構造函數
Wifi::Wifi(const char* data)
{cout << "構造函數" << endl;this->data = new char[strlen(data) + 1]; // 分配內存strcpy(this->data, data); // 復制內容
}void Wifi::Transmit_data(){cout << "用Wifi發送數據:" << this->data << endl;
}Wifi::~Wifi()
{cout << "~Wifi" << endl;//delete []data;
}#endif // DEBUG
//主函數
#include "4G.h"
#include "bluetooth.h"
#include "send_data.h"
#include "wifi.h"
#include <iostream>int main(){
//——————————————————————————這里是使用指針——————————————————————————// A4G* fg = new A4G("今天天氣良好") ;// fg->Transmit_data();// Blue_tooth* bt = new Blue_tooth("今天天氣良好") ;// bt->Transmit_data();// Wifi* wf =new Wifi("今天天氣良好") ;// wf->Transmit_data();
//__________________________這里使用引用——————————————————————————————\
//自動析構
A4G fg =  A4G("今天天氣良好") ;
fg.Transmit_data();
//自動析構
Blue_tooth bt =   Blue_tooth("今天天氣良好") ;
bt.Transmit_data();// Blue_tooth* bt = new Blue_tooth("今天天氣良好") ;
// bt->Transmit_data();Wifi* wf =new Wifi("今天天氣良好") ;
wf->Transmit_data();
delete wf;return 0;
}

?多態實現原理

一、虛函數表(vtable)與虛指針(vptr)
  1. 核心機制

    • 虛函數表(vtable):每個包含虛函數的類在編譯時生成一個虛函數表,表中存儲該類所有虛函數的地址。

    • 虛指針(vptr):每個對象在內存中隱含一個指向其虛函數表的指針(vptr),用于運行時動態綁定。

  2. 內存布局示例

    class Hero {
    public:virtual void skill() {}string name;static int count;
    };
    • 32位系統

      • vptr?占4字節,string?占24字節(實現依賴),總大小?4 + 24 = 28?字節(對齊可能調整)。

    • 64位系統

      • vptr?占8字節,string?占32字節(實現依賴),總大小?8 + 32 = 40?字節。

  3. 調試驗證(GDB)

    • ?調試程序

      gdb a.out

    • 設置斷點

      b 函數名/行號

    • 運行調試

      r

    • 單步執行

      n

  4. set print object on/off????????是否以更易于閱讀的方式打印結構體或類對象
  5. set print pretty on/off????????控制數組打印
  6. set print array on????????查看對象信息
  7. print object????????數據顯示格式
  • x 按十六進制格式顯示變量
  • d 按照十進制格式顯示變量
  • u 按十六進制格式顯示無符號整型
  • o 按八進制格式顯示變量
  • t 按二進制格式顯示變量
  • a 按十六進制格式顯示變量
  • c 按字符格式顯示變量
  • f 按浮點數格式顯示變量

?

虛函數表

  • 虛函數表(vtable)是C++中實現多態性的核心機制,它存放了類中虛函數的入口地址。

  • _vptr是每個包含虛函數的類的對象中的一個隱藏指針,指向該類的虛函數表。

  • 編譯器自動生成和維護虛函數表以及_vptr,開發者無需手動干預。

  • 在GDB中調試時,可以查看_vptr的值以及它所指向的虛函數表,以了解對象的多態行為。

二、繼承與虛函數表覆蓋
  1. 子類繼承父類虛函數表

    • 子類繼承父類的虛函數表,若重寫父類虛函數,則替換對應條目。

    • 示例

      class Houyi : public Hero {
      public:virtual void skill() override {}
      };
      • 子類?Houyi?的虛函數表中?skill()?地址指向?Houyi::skill()

  2. 調試驗證

    (gdb) print houyi
    $1 = (Houyi) {<Hero> = {_vptr.Hero = 0x56558e7c <vtable for Houyi+8>},looks = 20
    }
三、靜態綁定與動態綁定
特性靜態綁定動態綁定
綁定時機編譯期(根據類型確定調用)運行期(根據對象實際類型確定)
實現方式函數重載、模板虛函數(virtual
靈活性

關鍵區別

  • 動態綁定依賴虛函數表:通過?vptr?找到虛函數表,再根據實際對象類型調用對應函數。

  • 多態場景:必須通過基類指針或引用操作子類對象。

四、32位與64位系統下的對象大小
  1. 基本規則

    • 指針大小:32位系統4字節,64位系統8字節。

    • 內存對齊:通常按最大成員類型對齊(如?int?按4字節對齊)。

  2. 復雜繼承示例

    class C : public A, public B {int c;
    };
    • 32位系統

      • A?含?vptr(4) +?int a(4) = 8字節。

      • B?含?vptr(4) +?int b(4) = 8字節。

      • C?含?A(8) +?B(8) +?int c(4) = 20字節(對齊到8的倍數→24字節)。

    • 64位系統

      • A?含?vptr(8) +?int a(4) → 對齊到8字節 → 16字節。

      • B?含?vptr(8) +?int b(4) → 對齊到8字節 → 16字節。

      • C?總大小:16 + 16 + 4 = 36 → 對齊到8的倍數→40字節。

六、總結
  • 多態實現核心:虛函數表與虛指針的動態綁定機制。

  • 內存管理關鍵:理解不同系統下的指針大小和對齊規則。

  • 調試工具:GDB可用于驗證虛函數表和對象內存布局。

  • 設計原則:優先使用虛函數實現動態多態,避免手動管理內存錯誤。

重載、覆蓋和隱藏

一、重載(Overloading)

定義:在同一作用域內定義多個同名函數或運算符,但參數列表(參數類型、數量或順序)不同。
特點

  • 編譯時多態,由編譯器根據參數列表決定調用哪個函數。

  • 適用于函數和運算符。

  • 函數簽名必須不同(返回類型不影響)。

  • const修飾符、引用或指針類型的參數可區分重載。

示例

int add(int a, int b) { return a + b; }  
double add(double a, double b) { return a + b; }
二、覆蓋(Overriding)

定義:派生類重新定義基類的虛函數,實現運行時多態。
條件

  • 基類函數必須為虛函數(virtual)。

  • 函數簽名(名稱、參數列表、返回類型)完全相同。

  • 訪問權限可以不同,但通常保持一致。

特點

  • 通過基類指針或引用調用時,實際執行派生類的函數。

  • 依賴虛函數表(vtable)實現動態綁定。

示例

class Base {  
public:  virtual void show() { cout << "Base"; }  
};  
class Derived : public Base {  
public:  void show() override { cout << "Derived"; }  
};
三、隱藏(Hiding)

定義:派生類中的成員(函數或屬性)與基類同名,導致基類成員在派生類作用域中不可見。
類型

  1. 函數隱藏

    • 派生類函數與基類函數同名但參數不同,或同名同參數但基類函數非虛。

    • 基類函數被隱藏,需通過作用域解析符(Base::func())訪問。

  2. 屬性隱藏

    • 派生類定義與基類同名的成員變量,直接訪問時使用派生類版本。

示例

class Base {  
public:  void func() { cout << "Base::func"; }  int value;  
};  
class Derived : public Base {  
public:  void func(double) { cout << "Derived::func"; } // 隱藏Base::func()  double value; // 隱藏Base::value  
};
關鍵區別
特性重載覆蓋隱藏
作用域同一作用域基類與派生類之間基類與派生類之間
函數簽名必須不同必須相同可不同或相同(非虛)
虛函數不要求必須為虛函數不要求
多態性編譯時多態運行時多態無多態性

抽象類與泛型?

一、抽象類(Abstract Class)

定義
????????抽象類是一種不能被實例化的類,用于定義接口或基類,要求派生類必須實現其純虛函數。

核心特點

  1. 純虛函數

    • 聲明格式為?virtual 返回類型 函數名() = 0;,無函數體。

    • 派生類必須實現所有純虛函數,否則派生類仍為抽象類。

    class AbstractClass {
    public:virtual void pureVirtual() = 0; // 純虛函數
    };
  2. 不能實例化

    • 直接實例化抽象類會導致編譯錯誤。

    AbstractClass obj; // 錯誤:無法創建抽象類對象
  3. 基類作用

    • 抽象類通過指針或引用實現多態,指向派生類對象。

    AbstractClass* ptr = new DerivedClass();
    ptr->pureVirtual(); // 調用派生類的實現
  4. 構造與析構函數

    • 抽象類可以有構造函數和析構函數,但析構函數通常聲明為虛函數以確保正確釋放資源。

應用場景

  • 定義統一接口:要求所有派生類遵循相同的接口規范。

  • 代碼復用:基類提供公共邏輯,派生類實現具體功能。

示例

class Shape {  // 抽象類
public:virtual double area() = 0;  // 純虛函數virtual ~Shape() {}         // 虛析構函數
};class Circle : public Shape {
private:double radius;
public:Circle(double r) : radius(r) {}double area() override {    // 必須實現純虛函數return 3.14 * radius * radius;}
};
二、泛型(Generics)

定義
泛型編程通過模板(Templates)實現類型無關的代碼,支持在編譯時根據具體類型生成代碼。

核心機制

  1. 函數模板

    • 定義與類型無關的通用函數,支持多種數據類型。

    template <typename T>
    T add(T a, T b) {return a + b;
    }
    • 調用方式

      • 自動推導:add(3, 4);

      • 顯式指定:add<double>(3.14, 2.71);

  2. 類模板

    • 定義與類型無關的類,成員變量和函數的類型由模板參數決定。

    template <typename T>
    class Box {
    private:T content;
    public:Box(T c) : content(c) {}T getContent() { return content; }
    };
  3. 模板繼承

    • 派生類繼承類模板時,需指定父類的具體類型或自身也聲明為模板。

    template <typename T>
    class Base { /* ... */ };class DerivedInt : public Base<int> { /* ... */ };  // 指定類型template <typename T1, typename T2>
    class DerivedTemplate : public Base<T2> { /* ... */ };  // 派生類模板

標準模板庫(STL)

  • 容器:如?vectorlistmap,用于存儲和管理數據。

    vector<int> vec = {1, 2, 3};
    for (int val : vec) cout << val << " ";
  • 算法:如?sortfind,提供通用操作。

    sort(vec.begin(), vec.end());

應用場景

  • 通用數據結構:如鏈表、隊列等,支持多種數據類型。

  • 類型無關算法:如排序、查找,避免重復代碼。

三、抽象類與泛型的對比
特性抽象類泛型
核心目的定義接口,強制派生類實現邏輯編寫類型無關的通用代碼
多態性運行時多態(虛函數)編譯時多態(模板實例化)
實例化限制不能實例化抽象類模板類/函數在實例化時生成具體代碼
適用場景面向對象設計中的繼承與多態需要支持多種數據類型的通用邏輯
四、關鍵總結
  1. 抽象類

    • 用于定義接口,強制派生類實現特定功能。

    • 通過虛函數實現運行時多態,支持基類指針操作派生類對象。

  2. 泛型

    • 通過模板實現代碼的通用性,避免重復邏輯。

    • 在編譯時生成類型相關代碼,提高效率和靈活性。

  3. 結合使用

    • 抽象類和泛型可結合使用,例如定義泛型容器時,容器元素類型可以是抽象類的派生類。

示例代碼

// 抽象類與泛型結合
template <typename T>
class GenericContainer {
private:vector<T*> items;
public:void addItem(T* item) { items.push_back(item); }void processAll() {for (T* item : items) item->process();}
};class BaseItem {  // 抽象類
public:virtual void process() = 0;virtual ~BaseItem() {}
};class DerivedItem : public BaseItem {
public:void process() override { /* ... */ }
};

順序容器

一、順序容器概覽

順序容器用于存儲具有線性關系的元素,支持在任意位置插入、刪除和訪問元素。C++ STL 中的順序容器包括:

容器特性優點缺點
vector動態數組,支持隨機訪問。快速隨機訪問(O(1))。中間插入/刪除效率低(O(n))。
deque雙端隊列,支持兩端高效操作。兩端插入/刪除高效(O(1))。中間操作效率低(O(n))。
list雙向鏈表,任意位置插入/刪除高效。任意位置操作高效(O(1))。不支持隨機訪問(O(n))。
forward_list單向鏈表(C++11),內存占用更小。內存效率高。僅支持單向遍歷。
array固定大小數組(C++11)。棧上分配,性能高。大小不可變。
二、核心操作與成員函數
1. 通用操作
  • 插入push_backpush_frontdequelist)、insert

  • 刪除pop_backpop_frontdequelist)、erase

  • 訪問operator[]atfrontback

  • 容量管理sizeresizecapacityreservevectordeque)。

2. 容器特有操作
容器特有操作
vectorshrink_to_fit(釋放多余內存)。
dequepush_frontpop_front
listsplice(合并鏈表)、merge(有序合并)、remove(刪除特定值)。
forward_list僅提供單向迭代器,無?size()?函數。
三、性能對比與適用場景
場景推薦容器理由
頻繁隨機訪問vectorarray支持 O(1) 隨機訪問。
頻繁兩端操作deque兩端插入/刪除高效。
頻繁任意位置插入/刪除list鏈表結構無需移動元素。
內存敏感forward_list內存占用更小。
固定大小需求array編譯時確定大小,無動態分配開銷。
四、示例代碼要點
1.?vector?示例
vector<int> v1(3);          // 初始化為3個0
v1.push_back(20);           // 末尾添加元素
v1.insert(v1.begin()+2, 2, 30); // 在位置2插入兩個30
  • 注意vector?擴容時可能觸發 2 倍內存分配,可通過?reserve?預分配空間優化。

2.?deque?示例
deque<int> d{1, 2, 3, 4};
d.push_front(200);          // 頭部插入200
d.push_back(50);            // 尾部插入50
  • 內存分布:由多個連續內存塊組成,插入時無需整體復制。

3.?list?示例
list<int> l = {7, 5, 16, 8};
l.push_front(25);           // 頭部插入25
l.remove(5);                // 刪除所有值為5的元素
  • 不支持?operator[],需通過迭代器遍歷。

關聯容器?

一、關聯容器概覽

關聯容器通過平衡二叉樹(紅黑樹)實現,元素按特定規則排序,提供高效的查找(O(log n))、插入和刪除操作。主要包含以下四種容器:

容器特性適用場景
set元素唯一,默認升序排列。去重且需要有序訪問的場景。
multiset允許重復元素,默認升序排列。允許重復的有序集合。
map鍵值對(key-value),鍵唯一,按鍵排序。鍵唯一且需按鍵快速查找的映射。
multimap鍵可重復,按鍵排序。一鍵對應多值的映射。
二、核心特性與操作
1.?set?與?multiset
  • 共同點

    • 底層基于紅黑樹,元素自動排序。

    • 支持插入(insert)、刪除(erase)、查找(find)等操作。

  • 區別

    • set?元素唯一,multiset?允許重復。

  • 示例代碼

    set<int> s{1, 5, 3};
    s.insert(2);      // 插入元素,自動排序
    s.erase(1);       // 刪除元素multiset<int> ms{1, 1, 3};
    ms.insert(1);     // 允許重復
2.?map與?multimap
  • 共同點

    • 存儲鍵值對,按鍵排序。

    • 支持通過鍵快速查找值(findoperator[])。

  • 區別

    • map?鍵唯一,multimap?鍵可重復。

  • 示例代碼

    map<string, float> m;
    m["apple"] = 5.0;              // 插入鍵值對
    m.insert({"orange", 2.8});multimap<string, float> mm;
    mm.insert({"apple", 5.0});
    mm.insert({"apple", 8.3});     // 允許重復鍵
3. 常用操作
  • 插入

    s.insert(value);          // set/multiset
    m.insert({key, value});   // map/multimap
  • 刪除

    s.erase(value);           // 刪除特定值
    m.erase(key);             // 刪除特定鍵
  • 查找

    auto it = s.find(value);  // 返回迭代器
    auto it = m.find(key);    // 返回鍵對應的迭代器
  • 遍歷

    for (auto it = s.begin(); it != s.end(); ++it) {cout << *it << endl;  // set/multiset
    }
    for (auto& [key, val] : m) {cout << key << ":" << val << endl;  // map/multimap
    }
三、關鍵區別與選擇
對比項set?vs?multisetmap?vs?multimap
元素唯一性set唯一,multiset可重復。map鍵唯一,multimap鍵可重復。
查找方式直接按值查找。按鍵查找值。
典型應用去重集合、有序數據存儲。字典、配置表、多值映射。
四、高級操作與技巧
1.?multimap?的多值鍵處理
  • equal_range?方法:查找所有匹配鍵的元素范圍。

    auto range = mm.equal_range("apple");
    for (auto it = range.first; it != range.second; ++it) {cout << it->second << endl;  // 輸出所有"apple"對應的值
    }
2. 自定義排序規則
  • 通過比較函數模板參數

    set<int, greater<int>> s;  // 降序排列
    map<string, int, Compare> m;  // 自定義鍵比較規則
3. 性能優化
  • 避免頻繁插入/刪除:紅黑樹的自平衡操作有開銷。

  • 使用?emplace?替代?insert:減少臨時對象構造。

五、應用場景與實戰
  1. 去重與排序

    • 使用?set?或?map?自動去重并排序數據。

  2. 頻率統計

    • 使用?map<string, int>?統計單詞頻率。

  3. 多值映射

    • 使用multimap存儲學生ID到多個課程成績的映射。

容器適配器、迭代器與函數對象

一、容器適配器

核心概念

  1. 定義:基于現有容器封裝,提供特定接口(如棧、隊列)。

  2. 類型與底層實現

    • stack:默認基于?deque(支持高效首尾操作)。

    • queue:默認基于?deque(避免空間浪費)。

    • priority_queue:默認基于?vector(需連續內存構建堆)。

  3. 特性

    • 不直接支持迭代器,僅通過適配接口操作(如?push/pop)。

    • priority_queue?默認大根堆,元素按優先級出隊。

代碼示例?

queue

#include <iostream>
#include <queue>
using namespace std;
int main(){
queue<int> q;
q.push(17);
q.push(24);
q.push(86);
// 查看隊首元素
cout << "queue front:" << q.front() << endl;
// 進行出隊操作
while(!q.empty()){
cout << q.front() << endl;
q.pop();
}
return 0;
}

stack

#include <iostream>
#include <stack>
using namespace std;
int main(){
stack<int> s;
s.push(17);
s.push(24);
s.push(86);
// 查看棧頂元素
cout << "stack top:" << s.top() << endl;
// 進行出棧操作
while(!s.empty()){
cout << s.top() << endl;
s.pop();
}
return 0;
}

?priority_queue

#include <iostream>
#include <queue>
using namespace std;
int main()
{priority_queue<int> pq;pq.push(36);pq.push(24);pq.push(86);// 查看隊首元素cout << "queue front:" << pq.top() << endl;// 進行出隊操作while (!pq.empty()){cout << pq.top() << endl;pq.pop();}
二、迭代器

核心概念

  1. 作用:提供統一訪問容器元素的接口,抽象底層實現(如鏈表、數組)。

  2. 實現關鍵

    • 重載操作符(++,?*,?->,?==,?!=)。

    • begin()?返回首元素迭代器,end()?返回尾后迭代器。

  3. 分類

    • 輸入/輸出迭代器、前向/雙向/隨機訪問迭代器(STL容器支持不同類別)。

代碼示例與修正

  • 自定義鏈表迭代器

    // 構造函數語法錯誤修正:
    iterator(ListNode<T> *ptr) : ptr(ptr) {}  // 原代碼缺少初始化列表
    // 比較操作符修正:
    bool operator==(const iterator &other) const { return ptr == other.ptr;  // 原代碼中誤寫為 other_ptr
    }

應用場景

  • 泛型編程:STL算法(如?sort,?find)通過迭代器操作任意容器。

  • 遍歷與修改:如?for (auto it = vec.begin(); it != vec.end(); ++it)

三、函數對象(仿函數)

核心概念

  1. 定義:重載?operator()?的類實例,可像函數一樣調用。

  2. 優點

    • 狀態保存:成員變量記錄調用間狀態(如計數器)。

    • 靈活性:可作為模板參數傳遞(如STL算法?sort?的比較器)。

  3. STL內建函數對象

    • 算術plus<T>,?minus<T>

    • 關系less<T>,?greater<T>

    • 邏輯logical_and<T>,?logical_not<T>

代碼示例與修正

  • 語法錯誤修正

    class SelfCompare {
    public:bool operator()(int n1, int n2) {  // 原代碼缺少括號閉合return n1 > n2;}
    };

應用場景

  • STL算法:如?transform?使用仿函數對元素批量操作。

  • 自定義策略:如排序規則、條件過濾(find_if)。

對比與聯系
特性容器適配器迭代器函數對象
核心功能封裝特定數據結構接口統一容器元素訪問方式封裝可調用邏輯與狀態
底層依賴基于現有容器(如deque)依賴容器內部結構實現獨立類或STL內建對象
典型應用棧、隊列、優先隊列遍歷、算法泛化策略模式、STL算法參數
總結
  1. 容器適配器:通過封裝簡化特定數據結構操作,隱藏底層細節。

  2. 迭代器:實現容器與算法的解耦,是泛型編程的基石。

  3. 函數對象:提供靈活的可調用單元,優于函數指針(支持狀態和內聯優化)。

綜合應用示例

// 使用 priority_queue(適配器)+ 仿函數(自定義比較規則)
struct Compare {bool operator()(int a, int b) { return a > b; }  // 小根堆
};
priority_queue<int, vector<int>, Compare> pq;
 

  • 這是本人的學習筆記不是獲利的工具,小作者會一直寫下去,希望大家能多多監督
  • 文章會每攢夠兩篇進行更新發布
  • 感謝各位的閱讀希望我的文章會對諸君有所幫助

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/77154.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/77154.shtml
英文地址,請注明出處:http://en.pswp.cn/web/77154.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

文件上傳詳細版

文件上傳造成因素&#xff1a; 文件路徑過濾不嚴格&#xff0c;可能通過遍歷目錄來獲得文件&#xff0c;也可能通過文件上傳對重要文件案進行覆蓋&#xff0c;還可能對文件拓展名和文件類型過濾不嚴格&#xff0c;可以上傳任意文件到web公開目錄上&#xff0c;進而遠程控制服務…

華為網路設備學習-19 IGP路由專題-路由策略

一、 二、 注意&#xff1a; 當該節點匹配模式為permit下時&#xff0c;參考if else 當該節點匹配模式為deny下時&#xff1a; 1、該節點中的apply子語句不會執行。 2、如果滿足所有判斷&#xff08;if-match&#xff09;條件時&#xff0c;拒絕該節點并跳出&#xff08;即不…

智能指針之設計模式4

前面的文章介紹了使用工廠模式來封裝智能指針對象的創建過程&#xff0c;下面介紹一下工廠類 enable_shared_from_this的實現方案。 4、模板方法模式 在前面的文章分析過&#xff0c;enable_shared_from_this<T>類是一個工廠基類&#xff0c;提供的工廠方法是shared_f…

【Nova UI】十、打造組件庫第一個組件-圖標組件(下):從.svg 到 SVG Vue 組件的高效蛻變?

序言 在組件庫開發的精彩旅程中&#x1f680;&#xff0c;我們已經成功打造并完善了圖標組件體系&#xff0c;賦予其強大的功能和豐富的表現力&#x1f389;。然而&#xff0c;隨著業務版圖的不斷擴張&#x1f310;&#xff0c;手動逐個編寫 SVG Vue 組件的傳統方式&#xff0…

Golang | 倒排索引

文章目錄 倒排索引的設計倒排索引v0版實現 倒排索引的設計 通用搜索引擎 v.s. 垂直搜索引擎&#xff1a; 通用搜索引擎&#xff1a;什么都可以搜索&#xff0c;更加智能化垂直搜索引擎&#xff1a;只能搜自家數據庫里面的內容&#xff0c;一般都帶著搜索條件&#xff0c;搜索一…

Windows 10 上運行 Ollama 時遇到 llama runner process has terminated: exit status 2

在 Windows 10 上運行 Ollama 時遇到 llama runner process has terminated: exit status 2 錯誤&#xff0c;可能是由多種原因引起的。以下是逐步解決方案&#xff1a; 1. 檢查 Ollama 服務狀態 按 Win R 輸入 services.msc&#xff0c;找到 Ollama 服務&#xff0c;確保其狀…

PCI 總線學習筆記(五)

PCI 總線學習系列&#xff0c;參考自 技術大牛博客&#xff1a; PCIe 掃盲系列博文連載目錄篇 書籍&#xff1a;王齊老師的《PCI Express 體系結構導讀》 下面的文章中加入了自己的一些理解和實際使用中遇到的一些場景&#xff0c;供日后查詢和回憶使用 PCI 總線定義了兩類配置…

Spring Cloud Alibaba VS Spring Cloud

??Spring Cloud Alibaba 與 Spring Cloud 組件對比? ??服務發現與注冊中心? 功能???Spring Cloud???Spring Cloud Alibaba?對比說明??核心組件?EurekaNacosNacos 支持動態配置管理、健康檢查更靈活&#xff0c;且提供 DNS 服務發現能力。????健康檢查??…

Java—— 常見API介紹 第五期

JDK8以后新增的時間相關類 Date類ZoneId&#xff1a;時區Instant&#xff1a;時間戳ZoneDateTime&#xff1a;帶時區的時間 日期格式化類 SimpleDateFormat DateTimeFormatter&#xff1a;用于時間的格式化和解析 日歷類 Calendar LocalDate&#xff1a;年、月、日LocalTime…

Java與Kotlin在Android開發中的全面對比分析

趨勢很重要 語言發展背景與現狀 Android操作系統自2008年正式發布以來&#xff0c;Java長期作為其主要的開發語言。這種選擇源于Java語言的跨平臺特性、成熟的生態系統以及廣泛開發者基礎。然而&#xff0c;隨著移動開發需求的快速演變&#xff0c;Java在Android開發中逐漸暴…

第一部分:git基本操作

目錄 1、git初識 1.1、存在的問題 1.2、版本控制器 1.3、git安裝 1.3.1、CentOS平臺 1.3.2、ubuntu平臺 2、git基本操作 2.1、創建倉庫 2.2、配置git 3、工作區、暫存區、版本庫 4、基本操作 4.1、場景一 4.2、場景二 4.3、修改文件 5、版本回退 6、撤銷修改 …

正則表達式與python使用

一、Python正則表達式基礎 1. 導入模塊 Python通過 re 模塊實現正則表達式功能&#xff0c;需先導入模塊&#xff1a; import re2. 核心語法 普通字符&#xff1a;直接匹配字面值&#xff08;如 a 匹配字符 a&#xff09;。元字符&#xff1a; \d&#xff1a;匹配數字&…

從FP32到BF16,再到混合精度的全景解析

筆者做過目標檢測模型、超分模型以及擴散生成模型。其中最常使用的是單精度FP32、半精度FP16、BF16。 雙精度"FP64"就不說了&#xff0c;不太會用到。 #1. 單精度、半精度和混合精度 單精度&#xff08;FP32&#xff09;、半精度&#xff08;FP16&#xff09;和混合…

Hot100方法及易錯點總結2

本文旨在記錄做hot100時遇到的問題及易錯點 五、234.回文鏈表141.環形鏈表 六、142. 環形鏈表II21.合并兩個有序鏈表2.兩數相加19.刪除鏈表的倒數第n個節點 七、24.兩兩交換鏈表中的節點25.K個一組翻轉鏈表(坑點很多&#xff0c;必須多做幾遍)138.隨機鏈表的復制148.排序鏈表 N…

不在同一個局域網的遠程桌面連接怎么設置?本地內網計算機讓其他網絡遠程訪問6種常用方法

遠程桌面是一種重要的技術&#xff0c;它允許用戶通過網絡遠程訪問和控制另一臺計算機的桌面界面。但是&#xff0c;當被控制端和控制端不在同一個局域網內時&#xff0c;就需要進行一些額外的配置。本文將詳細介紹在不同局域網下設置遠程桌面的步驟&#xff0c;以幫助讀者順利…

天機學堂day10作業,完善兌換優惠券功能

UserCouponServiceImpl /*** 兌換碼兌換優惠券* param code*/TransactionalOverridepublic void exchangeCoupon(String code) {//1、校驗code是否為空if (StringUtils.isBlank(code)) {throw new BadRequestException("非法參數&#xff01;");}//2、解析兌換碼&…

JAVA工程師面試題(七)

1、遞歸實現1,1,2,3,5,8,….第30個數是多少&#xff1f; public static int Foo(int i) { if (i < 0) return 0; else if(i > 0 && i < 2) return 1; else return Foo(i -1) Foo(i - 2); }…

Qt基礎009(HTTP編程和QJSON)

文章目錄 軟件開發網絡架構BS架構/CS架構 HTTP基本概念QT的HTTP編程JSON數據概述QT生成JSON數據QT解析JSON數據 軟件開發網絡架構 BS架構/CS架構 ? 在計算機網絡和軟件開發中&#xff0c;CS架構&#xff08;Client-Server Architecture&#xff0c;客戶端-服務器架構&#x…

高精度電流檢測革命:同軸分流器的創新應用與技術演進

一、精密測量原理與結構創新 基于電磁場分布重構技術的新型同軸分流器&#xff0c;突破了傳統電流測量的物理限制。該器件采用三維環形電阻矩陣結構&#xff0c;通過多層級導電環的精密排列&#xff0c;實現了電流路徑的渦流自補償。區別于常規分流器的平板式設計&#xff0c;其…

【使用層次序列構建二叉樹(數據結構C)】

使用層次序列構建二叉樹&#xff08;C語言實現&#xff09; 在數據結構學習過程中&#xff0c;二叉樹的構建方式通常有遞歸建樹&#xff08;前序/中序&#xff09;和層次建樹&#xff08;廣度優先&#xff09;兩種。本文將介紹一種基于輔助隊列實現的層次建樹方法&#xff0c;并…