C++_類和對象(下)

【本節目標】

  • 再談構造函數
  • Static成員
  • 友元
  • 內部類
  • 匿名對象
  • 拷貝對象時的一些編譯器優化
  • 再次理解封裝

1. 再談構造函數

1.1 構造函數體賦值

在創建對象時,編譯器通過調用構造函數,給對象中各個成員變量一個合適的初始值。

class Date
{
public:Date(int year, int month, int day){_year = year;_month = month;_day = day;}
private:int _year;int _month;int _day;};

雖然上述構造函數調用之后,對象中已經有了一個初始值,但是不能將其稱為對對象中成員變量的初始化,構造函數體中的語句只能將其稱為賦初值,而不能稱作初始化。因為初始化只能初始化一次,而構造函數體內可以多次賦值。

1.2 初始化列表

初始化列表:以一個冒號開始,接著是一個以逗號分隔的數據成員列表,每個"成員變量"后面跟一個放在括號中的初始值或表達式

代碼演示:

在這里插入圖片描述

輸出結果:

在這里插入圖片描述

這段代碼主要是對一些必須要初始化的成員進行初始化操作,且通過調用成員函數實現對外面的變量進行修改的操作。

初始化列表:

初始化列表是在構造函數的參數列表之后,函數體之前,使用冒號 : 分隔,用于對類的成員變量進行初始化。

特點:

  • 初始化時機: 初始化列表是在對象創建時就對成員變量進行初始化,即在對象的內存分配完成后,立即調用成員變量的構造函數進行初始化。
  • 效率較高: 對于一些類型,如 const 成員變量、引用成員變量,必須使用初始化列表進行初始化。而且對于自定義類型的成員變量,使用初始化列表可以避免一次默認構造和一次賦值操作,提高效率。

構造函數的函數體:

構造函數的函數體是在初始化列表之后執行的代碼塊,用于對成員變量進行賦值操作。

特點:

  • 賦值時機: 構造函數的函數體是在成員變量已經完成初始化(默認初始化或使用初始化列表初始化)之后執行的,因此是一種先創建后賦值的操作。
  • 適用場景: 適用于需要在構造對象時進行一些額外的計算或邏輯處理,然后再對成員變量進行賦值的情況。

注:拷貝構造同樣也有初始化列表


拓展_1:

在這里插入圖片描述

在同時有缺省參數和傳遞構造函數參數的時候,會優先使用傳遞的參數進行初始化。


拓展_2:

在這里插入圖片描述

注:單參數構造函數的隱式類型轉換
A a = i ;
老版本:首先對i進行調用構造函數創建一個臨時的類對象,再將這個對象淺拷貝給類對象a的一個過程。
新版本:編譯器進行優化,對a進行直接初始化。


拓展_3:

在這里插入圖片描述

代碼解釋:

  1. 臨時對象的創建: 當執行 const A& ref = 5; 時,常量數字 5 作為參數調用 A 的構造函數 A(int i),創建了一個 A 類型的臨時對象。這個臨時對象是右值,因為它沒有一個具體的、持久的名稱,并且在表達式結束后原本會被銷毀。

  2. 常量左值引用綁定臨時對象: const A& ref 是一個常量左值引用,它可以綁定到這個臨時對象上,并且將臨時對象的生命周期延長到和 ref 的生命周期一致。所以,在 ref 的作用域內,我們可以通過 ref 安全地訪問臨時對象的成員函數,如 ref.print()。


拓展_4:

在這里插入圖片描述

在單參數的基礎上,多參數的傳參加上了花括號進行區分。


拓展_5:

在這里插入圖片描述


拓展_6:

在 C++ 中,成員函數調用時:

同類對象調用: 若形參為 const A&,因同類不同對象可互訪成員,仍能訪問該對象成員。

不同類對象調用: 當形參是 const A&,被調用的 A 類成員函數需為 const 成員函數,以確保調用時權限一致,避免修改 const 對象狀態。

易混淆重點:

  1. 不同類調用時,若以 const 引用接收對象,調用其成員函數,無論有無返回值,都需該函數為 const 成員函數以確保權限一致。

注:const對象只能調用const函數成員

案例演示:

在這里插入圖片描述


拓展_7:

在這里插入圖片描述

產生后果:

在這里插入圖片描述

注:頭文件中兩個不同類如果后續在聲明中需要調用,則需要注意先后順序。

初始化列表和函數體內賦值混合使用場景:

在這里插入圖片描述

【注意】

  1. 每個成員變量在初始化列表中只能出現一次(初始化只能初始化一次)

  2. 類中包含以下成員,必須放在初始化列表位置進行初始化:

  • const 成員變量: const 成員變量在初始化后不能再被賦值,因此必須在初始化列表中進行初始化。
  • 引用成員變量: 引用必須在定義時進行初始化,因此也必須在初始化列表中進行初始化。
  • 沒有默認構造函數的類類型成員變量: 如果類的成員變量是一個沒有默認構造函數的類類型,那么必須在初始化列表中顯式調用該類的構造函數進行初始化。
  1. 盡量使用初始化列表初始化,因為不管你是否使用初始化列表,對于自定義類型成員變量,
    一定會先使用初始化列表初始化。

  2. 成員變量在類中聲明次序就是其在初始化列表中的初始化順序,與其在初始化列表中的先后次序無關

課堂練習:

class A
{
public:A(int a):_a1(a),_a2(_a1){}void Print() {cout<<_a1<<" "<<_a2<<endl;}private:int _a2;int _a1;
};int main() 
{A aa(1);aa.Print();
}A. 輸出1  1
B.程序崩潰
C.編譯不通過
D.輸出1  隨機值  --> 正確

1.3 explicit關鍵字

構造函數不僅可以構造與初始化對象,對于單個參數或者除第一個參數無默認值其余均有默認值
的構造函數,還具有類型轉換的作用。

class Date
{
public:// 1. 單參構造函數,沒有使用explicit修飾,具有類型轉換作用// explicit修飾構造函數,禁止類型轉換---explicit去掉之后,代碼可以通過編譯explicit Date(int year):_year(year){}// 2. 雖然有多個參數,但是創建對象時后兩個參數可以不傳遞//沒有使用explicit修飾,具有類型轉換作用// explicit修飾構造函數,禁止類型轉換explicit Date(int year, int month = 1, int day = 1): _year(year), _month(month), _day(day){}Date& operator=(const Date& d){if (this != &d){_year = d._year;_month = d._month;_day = d._day;}return *this;}private:int _year;int _month;int _day;};void Test()
{Date d1(2022);// 用一個整形變量給日期類型對象賦值// 實際編譯器背后會用2023構造一個無名對象,最后用無名對象給d1對象進行賦值d1 = 2023;// 將1屏蔽掉,2放開時則編譯失敗,因為explicit修飾構造函數,禁止了單參構造函數類型轉換的作用
}

用explicit修飾構造函數,將會禁止構造函數的隱式轉換。

2. static成員

2.1 概念

聲明為static的類成員稱為類的靜態成員,用static修飾的成員變量,稱之為靜態成員變量;用static修飾成員函數,稱之為靜態成員函數靜態成員變量一定要在類外進行初始化。

面試題:實現一個類,計算程序中創建出了多少個類對象。

在這里插入圖片描述

注:如果聲明和定義分開,則靜態成員需要在定義中聲明。

輸出結果:

在這里插入圖片描述

注:靜態函數才能去調用靜態成員


通過各種形式訪問public靜態成員:

在這里插入圖片描述

靜態成員核心特性:

  1. 類級作用域: 屬于類本身而非實例,所有對象共享唯一副本
  2. 內存獨立: 存儲于靜態存儲區(全局 / 靜態區),生命周期與程序同步

訪問方式:

    • 推薦: 類名::成員名(編譯期綁定)
    • 允許: 對象名.成員名 或 指針->成員名(即使指針為空)
    • 原理: 不依賴對象實例,通過類元信息直接尋址

注: 類外面不可以訪問private權限成員。

示例:

class MyClass {
public:static int s_val;  // 聲明static void s_func() { /* ... */ }
};int MyClass::s_val = 0;  // 必須類外初始化int main() {MyClass* ptr = nullptr;ptr->s_val = 42;    // 合法,空指針訪問靜態成員MyClass::s_func();  // 更安全的訪問方式
}

問:當我們將靜態成員放入private權限時,該通過什么辦法拿到靜態成員數據

我們可以通過靜態成員函數,在靜態成員函數內調用靜態成員變量,這樣我們就可以通過類在外面訪問靜態成員函數拿到靜態成員變量的數據。

示例:

在這里插入圖片描述

畫圖詳解:

在這里插入圖片描述

拓展_1:

在這里插入圖片描述

靜態成員函數中不能訪問非靜態成員變量(只允許訪問靜態成員變量),因為靜態成員函數沒有this指針,所以無法指向對象類的私有成員。


拓展_2:

當我們不能使用關鍵字的情況下如何實現:1+2+…+n?

示例:

在這里插入圖片描述

通過創建裝有n個元素的Sum自定義類型數組,就可以調用n次構造函數,實現累加效果。

2.2 特性

  • 靜態成員所有類對象所共享,不屬于某個具體的對象,存放在靜態區
  • 靜態成員變量必須在類外定義,定義時不添加static關鍵字,類中只是聲明
  • 類靜態成員即可用 類名::靜態成員 或者 對象.靜態成員 來訪問
  • 靜態成員函數沒有隱藏的this指針,不能訪問任何非靜態成員
  • 靜態成員也是類的成員,受public、protected、private 訪問限定符的限制

3. 友元

友元提供了一種突破封裝的方式,有時提供了便利。但是友元會增加耦合度,破壞了封裝,所以友元不宜多用。

友元分為:友元函數友元類

3.1 友元函數

問題:現在嘗試去重載operator<<,然后發現沒辦法將operator<<重載成成員函數。因為cout的輸出流對象和隱含的this指針在搶占第一個參數的位置。 this指針默認是第一個參數也就是左操作數了。但是實際使用中cout需要是第一個形參對象,才能正常使用。所以要將operator<<重載成全局函數。但又會導致類外沒辦法訪問成員,此時就需要友元來解決。operator>>同理。

class Date
{
public:Date(int year, int month, int day){_year = year;_month = month;_day = day;}// d1 << cout; -> d1.operator<<(&d1, cout);  不符合常規調用
// 因為成員函數第一個參數一定是隱藏的this,所以d1必須放在<<的左側ostream& operator<<(ostream& _cout){_cout << _year << "-" << _month << "-" << _day << endl;return _cout;}
private:int _year;int _month;int _day;};

友元函數可以直接訪問類的私有成員,它是定義在類外部普通函數,不屬于任何類,但需要在
類的內部聲明,聲明時需要加friend關鍵字。

class Date
{friend ostream& operator<<(ostream& _cout, const Date& d);friend istream& operator>>(istream& _cin, Date& d);
public:Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}
private:int _year;int _month;int _day;
};ostream& operator<<(ostream& _cout, const Date& d)
{_cout << d._year << "-" << d._month << "-" << d._day;return _cout;   
}istream& operator>>(istream& _cin, Date& d)
{_cin >> d._year;_cin >> d._month;_cin >> d._day;return _cin;
}int main()
{Date d;cin >> d;cout << d << endl;return 0;
}

注:
接收參數需要嚴格符合類型對齊要求
比如:cout << d1 --> 接收形參:ostream& _cout, const Date& d。

【注意】

  • 友元函數可訪問類的私有和保護成員,但不是類的成員函數
  • 友元函數不能用const修飾
  • 友元函數可以在類定義的任何地方聲明,不受類訪問限定符限制
  • 一個函數可以是多個類的友元函數
  • 友元函數的調用與普通函數的調用原理相同

友元函數對比普通函數核心區別在于友元函數接受的指定類可以訪問private權限成員。

3.2 友元類

友元類的所有成員函數都可以是另一個類的友元函數,都可以訪問另一個類中的非公有成員。

  • 友元關系是單向的,不具有交換性。
    比如上述Time類和Date類,在Time類中聲明Date類為其友元類,那么可以在Date類中直接
    訪問Time類的私有成員變量,但想在Time類中訪問Date類中私有的成員變量則不行。

  • 友元關系不能傳遞
    如果C是B的友元, B是A的友元,則不能說明C時A的友元。

  • 友元關系不能繼承,在繼承位置再給大家詳細介紹。

class Time
{friend class Date;// 聲明日期類為時間類的友元類,則在日期類中就直接訪問Time類中的私有成員變量
public:Time(int hour = 0, int minute = 0, int second = 0): _hour(hour), _minute(minute), _second(second){}void Print_time(){cout << _hour << "/" << _minute << "/" << _second << endl;}
private:int _hour;int _minute;int _second;
};class Date
{
public:Date(int year = 2025, int month = 2, int day = 28):_year(year), _month(month), _day(day), _t(21, 29, 10){}void Print(){_t.Print_time();cout << _year << "/" << _month << "/" << _day << " - " <<_t._hour << "/" << _t._minute << "/" << _t._second << endl;}
private:int _year;int _month;int _day;Time _t;
};int main()
{Date d;d.Print();return 0;
}

【注意】

友元類和普通類的區別:

訪問權限:

  • 普通類: 只能訪問其他類的public成員,遵循封裝原則,保證數據安全。
  • 友元類: 可訪問授權類的所有成員,包括privateprotected成員,打破封裝限制。

關系性質:

  • 普通類: 類間相對獨立,通過公共接口交互。
  • 友元類: 與授權類存在特殊信任關系,關系單向,破壞一定封裝性。

代碼維護:

  • 普通類: 封裝性好,修改內部實現通常不影響其他類,可維護性高。
  • 友元類: 授權類成員變化可能影響友元類,耦合度高,維護較復雜。

4. 內部類

概念:如果一個類定義在另一個類的內部,這個內部類就叫做內部類。 內部類是一個獨立的類,
它不屬于外部類,更不能通過外部類的對象去訪問內部類的成員。外部類對內部類沒有任何優越
的訪問權限。

注意:內部類就是外部類的友元類,參見友元類的定義,內部類可以通過外部類的對象參數來訪
問外部類中的所有成員。但是外部類不是內部類的友元。

特性:

  1. 內部類可以定義在外部類的public、protected、private都是可以的。
  2. 注意內部類可以直接訪問外部類中的static成員,不需要外部類的對象/類名。
  3. sizeof(外部類)=外部類,和內部類沒有任何關系。

計算類大小:

在這里插入圖片描述

輸出結果:

在這里插入圖片描述

注: B類受A類域和訪問限定符的限制,其實他們是兩個獨立的類。


如何定義B類:

在這里插入圖片描述

當我們的內部類處于private權限時,我們通過以下辦法定義B類:

在這里插入圖片描述

通過內部類概念實現:1+2+…n的計算:

在這里插入圖片描述

輸出結果:

在這里插入圖片描述

4.1 內部類在 public 權限下的核心特性

  1. 可見性與創建
  • 內部類在public權限下對外部完全可見,可通過Outer::Inner直接創建對象。
  • 外部類成員函數可直接使用內部類名創建對象(無需類作用域限定符)。

示例:

在這里插入圖片描述

  1. 成員訪問規則
  • 內部類→外部類
    • 內部類可直接訪問外部類的public/protected/private成員(嵌套作用域特權)。

注:前提是內部類成員函數接收外部類類型。

    • 訪問非靜態成員需通過外部類對象 / 引用 / 指針傳遞。

  • 外部類→內部類

    • 外部類成員函數內通過實例化內部類對象可自由訪問內部類的public成員,若內部類成員為private,需通過friend聲明授權。
  1. 參數傳遞的注意事項
  • 內部類成員函數若需調用外部類的非const成員,形參必須為非const引用 / 指針(如Outer&)。

  • 若僅需調用const成員,可使用const Outer&,但此時無法修改外部類對象。

  1. 靜態成員的訪問
  • 內部類的靜態成員可通過Outer::Inner::StaticMember直接訪問,無需創建對象。

注:如果靜態成員為private權限,則受類規則限制,我們不能直接進行訪問,我們可以通過定義靜態成員函數返回靜態成員變量。


4.2 內部類在 private 權限下的核心特性

示例:

在這里插入圖片描述

  1. 可見性限制
  • 外部不可見: 內部類的可見性是由public或者private權限決定的,所以private權限的內部類無法被外部直接訪問或實例化。

  • 封裝性: 內部類的實現細節完全隱藏,外部代碼只能通過外部類的公共接口間接使用內部類。

  1. 訪問關系(容易混淆)
  • 外部類對于內部類的訪問依舊受制于訪問權限,可以訪問內部類的public權限下的成員,private權限的成員變量則需要通過外部類調用內部類自身public權限下成員函數才能間接訪問

  • 內部類可以類比是外部類天然的友元類但外部類并不是內部類的友元),可以直接調用外部類的各個權限下的成員變量或者成員函數。但本質上內部類能特殊訪問外部類是源自于它是外部類的成員類。

  • 若內部類聲明為static,則無法直接訪問外部類的非靜態成員(需通過對象訪問)。

  1. 靜態成員的特殊規則
  • private以及public權限下的內部類可以訪問外部類的靜態成員變量或者函數,因為靜態成員變量以及函數是屬于類的并不是屬于對象,所以對于內部類來說都可以通過類名+作用域限定符號進行訪問。

注: 內部類也可以可直接訪問外部類靜態成員,如同訪問自身成員。并不一定需要顯示訪問。

  • 不過,普通類不能直接通過 “類名 + 作用域限定符” 的方式去訪問另一個類中 private 權限下的靜態成員,仍然要遵循類的訪問權限規則。也就是說,只有類自身以及它的友元(友元類或者友元函數)才可以訪問這些 private 權限的靜態成員。

總結:

將內部類聲明為 private`是 C++ 中實現封裝的重要手段,它通過限制可見性和控制訪問權限,確保外部類的接口簡潔性,并將內部類的實現細節完全隱藏。這種設計尤其適用于工具類、輔助類或僅服務于外部類的底層邏輯。

  • 同類對象可以自由訪問彼此的私有成員(包括變量和函數),這是 C++ 封裝性的體現。

  • 外部代碼無法直接訪問私有成員 ,必須通過類的 public 接口或友元機制。

對比:

從宏觀設計角度來看:將 ?private 內部類視為外部類的“子成員”?,而 ?public 內部類視為“獨立但關聯的組件”?


5. 匿名對象

class A
{
public:A(int a = 0):_a(a){cout << "A(int a)" << endl}~A(){cout << "~A()" << endl;}
private:int _a;
};class Solution {
public:int Sum_Solution(int n) {//...return n;}};int main(){A aa1;// 不能這么定義對象,因為編譯器無法識別下面是一個函數聲明,還是對象定義//A aa1();// 但是我們可以這么定義匿名對象,匿名對象的特點不用取名字,// 但是他的生命周期只有這一行,我們可以看到下一行他就會自動調用析構函數A();A aa2(2);// 匿名對象在這樣場景下就很好用,當然還有一些其他使用場景,這個我們以后遇到了再說Solution().Sum_Solution(10);return 0;}

6. 編譯器優化

class A
{
public:A(int a = 0):_a(a){cout << "A(int a)" << endl;}A(const A& aa):_a(aa._a){cout << "A(const A& aa)" << endl;}A& operator=(const A& aa){cout << "A& operator=(const A& aa)" << endl;if (this != &aa){_a = aa._a;}return *this;}~A(){cout << "~A()" << endl;}
private:int _a;
};void f1(A aa)
{}A f2()
{A aa;return aa;
}int main()
{// 傳值傳參A aa1;f1(aa1);cout << endl;// 傳值返回f2();cout << endl;// 隱式類型,連續構造+拷貝構造->優化為直接構造f1(1);// 一個表達式中,連續構造+拷貝構造->優化為一個構造f1(A(2));cout << endl;// 一個表達式中,連續拷貝構造+拷貝構造->優化一個拷貝構造A aa2 = f2();cout << endl;// 一個表達式中,連續拷貝構造+賦值重載->無法優化aa1 = f2();cout << endl;return 0;
}

示例:

在這里插入圖片描述

輸出結果:

在這里插入圖片描述

在形參上我們使用了實參的拷貝類型,如果我們要使用引用類型的話就會出現問題。

如下報錯:

在這里插入圖片描述

結論:由于2和3案例中實參是臨時變量,一個臨時的變量是無法使用引用類型的;如果強行使用引用類型,則需要使用通過const 類名引用進行延長生命周期。


拓展_1:

在這里插入圖片描述

通過匿名對象以及缺省參數的使用可以在調用函數的時候不傳入任何實參也能調用函數。


拓展_2:

在這里插入圖片描述


拓展_3:

在這里插入圖片描述


本章完~

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

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

相關文章

連續數據離散化與逆離散化策略

數學語言描述&#xff1a; 在區間[a,b]中有一組符合某分布的數據&#xff1a; 1.求相同區間中另一組符合同樣分布的數據與這組數據的均方誤差 2.求區間中點與數據的均方誤差 3.求在區間中均勻分布的一組數據與這組數據的均方誤差 一&#xff1a;同分布數據隨機映射 假設在…

Redash:一個開源的數據查詢與可視化工具

Redash 是一款免費開源的數據可視化與協作工具&#xff0c;可以幫助用戶快速連接數據源、編寫查詢、生成圖表并構建交互式儀表盤。它簡化了數據探索和共享的過程&#xff0c;尤其適合需要團隊協作的數據分析場景。 數據源 Redash 支持各種 SQL、NoSQL、大數據和 API 數據源&am…

FreeRTOS的空閑任務

在 FreeRTOS 中&#xff0c;空閑任務&#xff08;Idle Task&#xff09; 是操作系統自動創建的一個特殊任務&#xff0c;其作用和管理方式如下&#xff1a; 1. 空閑任務創建 FreeRTOS 內核自動創建&#xff1a;當調用 vTaskStartScheduler() 啟動調度器時&#xff0c;內核會自…

Java進階之旅-day05:網絡編程

引言 在當今數字化的時代&#xff0c;網絡編程在軟件開發中扮演著至關重要的角色。Java 作為一門廣泛應用的編程語言&#xff0c;提供了強大的網絡編程能力。今天&#xff0c;我們深入學習了 Java 網絡編程的基礎知識&#xff0c;包括基本的通信架構、網絡編程三要素、IP 地址、…

大數據(4.3)Hive基礎查詢完全指南:從SELECT到復雜查詢的10大核心技巧

目錄 背景一、Hive基礎查詢核心語法1. 基礎查詢&#xff08;SELECT & FROM&#xff09;2. 條件過濾&#xff08;WHERE&#xff09;3. 聚合與分組&#xff08;GROUP BY & HAVING&#xff09;4. 排序與限制&#xff08;ORDER BY & LIMIT&#xff09; 二、復雜查詢實戰…

Synopsys:設計對象

相關閱讀 Synopsyshttps://blog.csdn.net/weixin_45791458/category_12812219.html?spm1001.2014.3001.5482 對于Synopsys的EDA工具&#xff08;如Design Compiler、PrimeTime、IC Compiler&#xff09;等&#xff0c;設計對象(Design Objects)是組成整個設計的抽象表示&…

【愚公系列】《高效使用DeepSeek》053-工藝參數調優

??【技術大咖愚公搬代碼:全棧專家的成長之路,你關注的寶藏博主在這里!】?? ??開發者圈持續輸出高質量干貨的"愚公精神"踐行者——全網百萬開發者都在追更的頂級技術博主! ?? 江湖人稱"愚公搬代碼",用七年如一日的精神深耕技術領域,以"…

深度學習篇---模型訓練(1)

文章目錄 前言一、庫導入與配置部分介紹 二、超參數配置簡介 三、模型定義1. 改進殘差塊2. 完整CNN模型 四、數據集類五、數據加載函數六、訓練函數七、驗證函數八、檢查點管理九、主函數十、執行入口十一、關鍵設計亮點總結1.維度管理2.數據標準化3.動態學習率4.梯度剪裁5.檢查…

題解:AT_abc241_f [ABC241F] Skate

一道經典的 bfs 題。 提醒&#xff1a;本題解是為小白專做的&#xff0c;不想看的大佬請離開。 這道題首先一看就知道是 bfs&#xff0c;但是數據點不讓我們過&#xff1a; 1 ≤ H , W ≤ 1 0 9 1\le H,W\le10^9 1≤H,W≤109。 那么我們就需要優化了&#xff0c;從哪兒下手…

【含文檔+PPT+源碼】基于微信小程序的鄉村振興民宿管理系統

項目介紹 本課程演示的是一款基于微信小程序的鄉村振興民宿管理系統&#xff0c;主要針對計算機相關專業的正在做畢設的學生與需要項目實戰練習的 Java 學習者。 1.包含&#xff1a;項目源碼、項目文檔、數據庫腳本、軟件工具等所有資料 2.帶你從零開始部署運行本套系統 3.該…

STM32定時器通道1-4(CH1-CH4)的引腳映射關系

以下是 STM32定時器通道1-4(CH1-CH4)的引腳映射關系的詳細說明,以常見型號為例。由于不同系列/型號差異較大,請務必結合具體芯片的參考手冊確認。 一、STM32F1系列(如STM32F103C8T6) 1. TIM1(高級定時器) 通道默認引腳重映射引腳(部分/完全)備注CH1PA8無互補輸出CH1…

bge-m3+deepseek-v2-16b+離線語音能力實現離線文檔向量化問答語音版

ollama run deepseek-v2:16b ollama pull bge-m3 1、離線聽寫效果的大幅度提升。50M 1.3G&#xff08;每次初始化都會很慢&#xff09;---優化到首次初始化使用0延遲響應。 2、文檔問答歷史問題處理與優化&#xff0c;文檔問答離線策略討論與參數暴露。 3、離線大模型答復中斷…

前端界面在線excel編輯器 。node編寫post接口獲取文件流,使用傳參替換表格內容展示、前后端一把梭。

首先luckysheet插件是支持在線替換excel內容編輯得但是瀏覽器無法調用本地文件&#xff0c;如果只是展示&#xff0c;讓后端返回文件得二進制文件流就可以了&#xff0c;直接使用luckysheet展示。 這里我們使用xlsx-populate得node簡單應用來調用本地文件&#xff0c;自己寫一個…

JavaScript學習20-Event事件對象

1.屬性 即點擊誰就打印出來誰 2.方法 未添加stopPropagatio方法&#xff1a; 添加stopPropagatio方法后&#xff1a;

FreeRTOS 啟動過程中 SVC 和 PendSV 的工作流程?

在 FreeRTOS 的啟動過程中,SVC(Supervisor Call) 和 PendSV(Pendable Service Call) 是兩個關鍵的系統異常,分別用于 首次任務啟動 和 任務上下文切換。它們的協作確保了從內核初始化到多任務調度的平滑過渡。以下是詳細的工作流程分析(以 ARM Cortex-M 為例): 1. SVC…

[自制調試工具]構建高效調試利器:Debugger 類詳解

一、引言 在軟件開發的漫漫征程中&#xff0c;調試就像是一位忠誠的伙伴&#xff0c;時刻陪伴著開發者解決代碼里的各類問題。為了能更清晰地了解程序運行時變量的狀態&#xff0c;我們常常需要輸出各種變量的值。而 Debugger 類就像是一個貼心的調試助手&#xff0c;它能幫我…

foobar2000 VU Meter Visualisation 插件漢化版 VU表

原英文插件點此 界面展示 下載 https://wwtn.lanzout.com/iheI22ssoybi 安裝方式 解壓安裝文件&#xff0c;文件名為&#xff1a;foo_vis_vumeter-0.10.2_CHINIESE.fb2k-component

消息中間件對比與選型指南:Kafka、ActiveMQ、RabbitMQ與RocketMQ

目錄 引言 消息中間件的定義與作用 消息中間件在分布式系統中的重要性 對比分析的四種主流消息中間件概述 消息中間件核心特性對比 消息傳遞模型 Kafka&#xff1a;專注于發布-訂閱模型 ActiveMQ&#xff1a;支持點對點和發布-訂閱兩種模型 RabbitMQ&#xff1a;支持點…

liunx輸入法

1安裝fcitx5 sudo apt update sudo apt install fcitx fcitx-pinyin 2配置為默認輸入法 設置-》系統-》區域和語言 點擊系統彈出語言和支持選擇鍵盤輸入法系統 3設置設置 fcitx-configtool 如果沒顯示需要重啟電腦 4配置fcitx 把搜狗輸入法放到第一位&#xff08;點擊下面…

WindowsPE文件格式入門05.PE加載器LoadPE

https://bpsend.net/thread-316-1-1.html LoadPE - pe 加載器 殼的前身 如果想訪問一個程序運行起來的內存,一種方法就是跨進程讀寫內存,但是跨進程讀寫內存需要來回調用api,不如直接訪問地址來得方便,那么如果我們需要直接訪問地址,該怎么做呢?.需要把dll注進程,注進去的代碼…