你知道C++多少——默認成員函數

🌈個人主頁:小新_-

🎈個人座右銘:“成功者不是從不失敗的人,而是從不放棄的人!”🎈

🎁歡迎各位→點贊👍 + 收藏?? + 留言📝

🏆所屬專欄:話說那些與C++的愛恨情仇? ?歡迎訂閱,持續更新中~~~

? ? ?? ?? ?

? ? ? ? ? ? ? ? ? ? ? ? ? ?讓小新帶著你快樂的學習吧~?

前言

如果一個類中什么成員都沒有,簡稱為空類。
空類中真的什么都沒有嗎?并不是,任何類在什么都不寫時,編譯器會自動生成以下 6個默認成員
函數。
默認成員函數:用戶沒有顯式實現,編譯器會生成的成員函數稱為默認成員函數。

1. 構造函數

1.1 概念

對于以下 Date 類:
class Date
{
public:void Init(int year, int month, int day){_year = year;_month = month;_day = day;}void Print(){cout << _year << "-" << _month << "-" << _day << endl;}
private:int _year;int _month;int _day;
};
int main()
{Date d1;d1.Init(2022, 7, 5);d1.Print();Date d2;d2.Init(2022, 7, 6);d2.Print();return 0;
}
對于 Date 類,可以通過 Init 公有方法給對象設置日期,但如果每次創建對象時都調用該方法設置
信息,未免有點麻煩,那能否在對象創建時,就將信息設置進去呢?----構造函數
構造函數是一個特殊的成員函數,名字與類名相同,創建類類型對象時由編譯器自動調用 ,以保證
每個數據成員都有 一個合適的初始值,并且 在對象整個生命周期內只調用一次。

1.2 特性

構造函數 是特殊的成員函數,需要注意的是,構造函數雖然名稱叫構造,但是構造函數的主要任
并不是開空間創建對象,而是初始化對象
其特征如下:
1. 函數名與類名相同。
2. 無返回值。
3. 對象實例化時編譯器 自動調用 對應的構造函數。
4. 構造函數可以重載。
?class Date{public:// 1.無參構造函數Date(){}// 2.帶參構造函數Date(int year, int month, int day){_year = year;_month = month;_day = day;}private:int _year;int _month;int _day;};void TestDate(){Date d1; // 調用無參構造函數Date d2(2015, 1, 1); // 調用帶參的構造函數// 注意:如果通過無參構造函數創建對象時,對象后面不用跟括號,否則就成了函數聲明// 以下代碼的函數:聲明了d3函數,該函數無參,返回一個日期類型的對象// warning C4930: “Date d3(void)”: 未調用原型函數(是否是有意用變量定義的?)Date d3();}
5. 如果類中沒有顯式定義構造函數,則 C++ 編譯器會自動生成一個無參的默認構造函數,一旦
用戶顯式定義編譯器將不再生成。
?class Date{public:/*// 如果用戶顯式定義了構造函數,編譯器將不再生成Date(int year, int month, int day){_year = year;_month = month;_day = day;}*/void Print(){cout << _year << "-" << _month << "-" << _day << endl;}private:int _year;int _month;int _day;};int main(){// 將Date類中構造函數屏蔽后,代碼可以通過編譯,因為編譯器生成了一個無參的默認構造函
//數// 將Date類中構造函數放開,代碼編譯失敗,因為一旦顯式定義任何構造函數,編譯器將不再
//生成// 無參構造函數,放開后報錯:error C2512: “Date”: 沒有合適的默認構造函數可用Date d1;return 0;}
6. 關于編譯器生成的默認成員函數,很多人會有疑惑:不實現構造函數的情況下,編譯器會
生成默認的構造函數。但是看起來默認構造函數又沒什么用? d 對象調用了編譯器生成的默
認構造函數,但是 d 對象 _year/_month/_day ,依舊是隨機值。也就說在這里 編譯器生成的
默認構造函數并沒有什么用??
解答: C++ 把類型分成內置類型 ( 基本類型 ) 和自定義類型。內置類型就是語言提供的數據類
型,如: int/char... ,自定義類型就是我們使用 class/struct/union 等自己定義的類型,看看
下面的程序,就會發現編譯器生成默認的構造函數會對自定類型成員 _t 調用的它的默認成員
函數。
class Time
{
public:Time(){cout << "Time()" << endl;_hour = 0;_minute = 0;_second = 0;}
private:int _hour;int _minute;int _second;
};
class Date
{
private:// 基本類型(內置類型)int _year;int _month;int _day;// 自定義類型Time _t;
};
int main()
{Date d;return 0;
}
注意: C++11 中針對內置類型成員不初始化的缺陷,又打了補丁,即: 內置類型成員變量在
類中聲明時可以給默認值
class Time
{
public:Time(){cout << "Time()" << endl;_hour = 0;_minute = 0;_second = 0;}
private:int _hour;int _minute;int _second;
};
class Date
{
private:// 基本類型(內置類型)int _year = 1970;int _month = 1;int _day = 1;// 自定義類型Time _t;
};
int main()
{Date d;return 0;
}
7. 無參的構造函數和全缺省的構造函數都稱為默認構造函數,并且默認構造函數只能有一個
注意: 無參構造函數、全缺省構造函數、我們沒寫編譯器默認生成的構造函數,都可以認為
是默認構造函數。
class Date
{
public:Date(){_year = 1900;_month = 1;_day = 1;}Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}
private:int _year;int _month;int _day;
};
// 以下測試函數能通過編譯嗎?
void Test()
{Date d1;
}

2.析構函數

2.1 概念

通過前面構造函數的學習,我們知道一個對象是怎么來的,那一個對象又是怎么沒呢的?--析構函數?
析構函數:與構造函數功能相反,析構函數不是完成對對象本身的銷毀,局部對象銷毀工作是由
編譯器完成的。而 對象在銷毀時會自動調用析構函數,完成對象中資源的清理工作

2.2 特性

析構函數 是特殊的成員函數,其 特征 如下:
1. 析構函數名是在類名前加上字符 ~(有取反的意思,個人理解)
2. 無參數無返回值類型。
3. 一個類只能有一個析構函數。若未顯式定義,系統會自動生成默認的析構函數。注意 :析構
函數不能重載
4. 對象生命周期結束時, C++ 編譯系統系統自動調用析構函數
typedef int DataType;
class Stack
{
public:Stack(size_t capacity = 3){_array = (DataType*)malloc(sizeof(DataType) * capacity);if (NULL == _array){perror("malloc申請空間失敗!!!");return;}_capacity = capacity;_size = 0;}void Push(DataType data){// CheckCapacity();_array[_size] = data;_size++;}// 其他方法...~Stack(){if (_array){free(_array);_array = NULL;_capacity = 0;_size = 0;
}}
private:DataType* _array;int _capacity;int _size;
};
void TestStack()
{Stack s;s.Push(1);s.Push(2);
}
5. 關于編譯器自動生成的析構函數,是否會完成一些事情呢?下面的程序我們會看到,編譯器
生成的默認析構函數,對自定類型成員調用它的析構函數。
class Time
{
public:~Time(){cout << "~Time()" << endl;}
private:int _hour;int _minute;int _second;
};
class Date
{
private:// 基本類型(內置類型)int _year = 1970;int _month = 1;int _day = 1;// 自定義類型Time _t;
};
int main()
{Date d;return 0;
}

程序運行結束后輸出:~Time()
?在main方法中根本沒有直接創建Time類的對象,為什么最后會調用Time類的析構函數?
?因為:main方法中創建了Date對象d,而d中包含4個成員變量,其中_year, _month,?
_day三個是?內置類型成員,銷毀時不需要資源清理,最后系統直接將其內存回收即可;而_t是Time類對象,所以在 d銷毀時,要將其內部包含的Time類的_t對象銷毀,所以要調用Time類的析構函數。但是:main函數中不能直接調用Time類的析構函數,實際要釋放的是Date類對象,所以編譯器會調用Date類的析構函 數,而Date沒有顯式提供,則編譯器會給Date類生成一個默認的析構函數,目的是在其內部調用Time類的析構函數,即當Date對象銷毀時,要保證其內部每個自定義對象都可以正確銷毀 main函數中并沒有直接調用Time類析構函數,而是顯式調用編譯器為Date類生成的默認析構函數
注意:創建哪個類的對象則調用該類的析構函數,銷毀那個類的對象則調用該類的析構函數

6. 如果類中沒有申請資源時,析構函數可以不寫,直接使用編譯器生成的默認析構函數,比如
Date 類;有資源申請時,一定要寫,否則會造成資源泄漏,比如 Stack

3.?拷貝構造函數

3.1 概念

在現實生活中,可能存在一個與你一樣的自己,我們稱其為雙胞胎。
那在創建對象時,可否創建一個與已存在對象一某一樣的新對象呢?--拷貝構造函數
拷貝構造函數 只有單個形參 ,該形參是對本 類類型對象的引用 ( 一般常用 const 修飾 ) ,在用 已存
在的類類型對象創建新對象時由編譯器自動調用

3.2特征

拷貝構造函數也是特殊的成員函數,其 特征 如下:
1. 拷貝構造函數 是構造函數的一個重載形式
2. 拷貝構造函數的 參數只有一個 必須是類類型對象的引用 ,使用 傳值方式編譯器直接報錯
因為會引發無窮遞歸調用。
class Date
{
public:Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}// Date(const Date& d) ? // 正確寫法Date(const Date& d) ? // 錯誤寫法:編譯報錯,會引發無窮遞歸{_year = d._year;_month = d._month;_day = d._day;}
private:int _year;int _month;int _day;
};
int main()
{Date d1;Date d2(d1);return 0;
}

語法邏輯上,會形成無窮遞歸
注意:在編譯器生成的默認拷貝構造函數中,內置類型是按照字節方式直接拷貝的,而自定
義類型是調用其拷貝構造函數完成拷貝的。
3. 若未顯式定義,編譯器會生成默認的拷貝構造函數。 默認的拷貝構造函數對象按內存存儲按
字節序完成拷貝,這種拷貝叫做 淺拷貝,或者值拷貝 。(默認生成淺拷貝)
class Time
{
public:Time(){_hour = 1;_minute = 1;_second = 1;}Time(const Time& t){_hour = t._hour;_minute = t._minute;_second = t._second;cout << "Time::Time(const Time&)" << endl;}
private:int _hour;int _minute;int _second;
};
class Date
{
private:// 基本類型(內置類型)int _year = 1970;int _month = 1;int _day = 1;// 自定義類型Time _t;
};
int main()
{Date d1;// 用已經存在的d1拷貝構造d2,此處會調用Date類的拷貝構造函數// 但Date類并沒有顯式定義拷貝構造函數,則編譯器會給Date類生成一個默認的拷貝構//造函數Date d2(d1);return 0;
}
4. 編譯器生成的默認拷貝構造函數已經可以完成字節序的值拷貝了 ,還需要自己顯式實現嗎?
當然像日期類這樣的類是沒必要的。那么下面的類呢?驗證一下試試?
// 這里會發現下面的程序會崩潰掉?這里就需要我們以后講的深拷貝去解決。
typedef int DataType;
class Stack
{
public:Stack(size_t capacity = 10){_array = (DataType*)malloc(capacity * sizeof(DataType));if (nullptr == _array){perror("malloc申請空間失敗");return;}_size = 0;_capacity = capacity;}void Push(const DataType& data){// CheckCapacity();_array[_size] = data;_size++;}~Stack(){if (_array){free(_array);_array = nullptr;_capacity = 0;_size = 0;}}
private:DataType* _array;size_t _size;size_t _capacity;
};
int main()
{Stack s1;s1.Push(1);s1.Push(2);s1.Push(3);s1.Push(4);Stack s2(s1);return 0;
}

注意:類中如果沒有涉及資源申請時,拷貝構造函數是否寫都可以;一旦涉及到資源申請
時,則拷貝構造函數是一定要寫的,否則就是淺拷貝。
故由3、4倆條我們總結出以下經驗:
5. 拷貝構造函數典型調用場景:
  1. 使用已存在對象創建新對象
  2. 函數參數類型為類類型對象
  3. 函數返回值類型為類類型對象
class Date
{
public:Date(int year, int minute, int day){cout << "Date(int,int,int):" << this << endl;}Date(const Date& d){cout << "Date(const Date& d):" << this << endl;}~Date(){cout << "~Date():" << this << endl;}
private:int _year;int _month;int _day;
};
Date Test(Date d)
{Date temp(d);return temp;
}
int main()
{Date d1(2022,1,13);Test(d1);return 0;
}
為了提高程序效率,一般對象傳參時,盡量使用引用類型,返回時根據實際場景,能用引用
盡量使用引用。

4.賦值運算符重載

4.1 運算符重載

C++ 為了增強代碼的可讀性引入了運算符重載 運算符重載是具有特殊函數名的函數 ,也具有其
返回值類型,函數名字以及參數列表,其返回值類型與參數列表與普通的函數類似。
函數名字為:關鍵字 operator 后面接需要重載的運算符符號
函數原型: 返回值類型 ?operator 操作符 ( 參數列表 )
為什么有運算符重載這一概念呢?以日期類舉個例子:
我們看到運算符有些有意義,有些無意義,所以一個類到底要重載那些運算符,要看重載是否有價值和意義
注意:
不能通過連接其他符號來創建新的操作符:比如 operator@
重載操作符必須有一個類類型參數
用于內置類型的運算符,其含義不能改變,例如:內置的整型 + ,不 能改變其含義
作為類成員函數重載時,其形參看起來比操作數數目少 1 ,因為成員函數的第一個參數為隱
藏的 this
.* 、::、sizeof、 ? : 、. 注意以上 5 個運算符不能重載。這個經常在筆試選擇題中出
現。

這里會發現運算符重載成全局的就需要成員變量是公有的,那么問題來了,假如把類的成員變量改為私有?則 operator 會報錯?,此時封裝性如何保證?
?這里其實可以用我們后面學習的友元解決,或者干脆重載成成員函數。

即當重載成為全局 無法訪問類的私有成員,解決方法:

1.提供get和set方法

2、友元(后面講)

3、重載為成員函數

成員函數的調用
我們來看看上面二者的匯編,可知二者等價
當全局函數和類成員函數同時存在時,會優先調用類成員函數

4.2?賦值運算符重載

5.1賦值重載理解
5.2? 賦值運算符重載格式
  1. 參數類型const T&,傳遞引用可以提高傳參效率
  2. 返回值類型T&,返回引用可以提高返回的效率,有返回值目的是為了支持連續賦值
  3. 檢測是否自己給自己賦值
  4. 返回*this :要復合連續賦值的含義
  5. 重載的賦值運算符函數參數只有一個,另一個通過this指針傳遞
class Date
{
public:Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}Date(const Date& d)//拷貝構造{_year = d._year;_month = d._month;_day = d._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;
};
但是, 不能實現連續賦值,如圖,會報錯
可以改為:

4.3傳值返回和傳引用返回區別

我們看到ref和d的地址相同,易知在引用返回中,ref是d的別名
2. 賦值運算符只能重載成類的成員函數不能重載成全局函數
3. 用戶沒有顯式實現時,編譯器會生成一個默認賦值運算符重載,以值的方式逐字節拷貝 。注
意:內置類型成員變量是直接賦值的,而自定義類型成員變量需要調用對應類的賦值運算符
重載完成賦值。
class Time
{
public:Time(){_hour = 1;_minute = 1;_second = 1;}Time& operator=(const Time& t){if (this != &t){_hour = t._hour;_minute = t._minute;_second = t._second;}return *this;}
private:int _hour;int _minute;int _second;
};
class Date
{
private:// 基本類型(內置類型)int _year = 1970;int _month = 1;int _day = 1;// 自定義類型Time _t;
};
int main()
{Date d1;Date d2;d1 = d2;return 0;
}
既然 編譯器生成的默認賦值運算符重載函數已經可以完成字節序的值拷貝了 ,還需要自己實
現嗎?當然像日期類這樣的類是沒必要的。那么下面的類呢?驗證一下試試?
typedef int DataType;
class Stack
{
public:Stack(size_t capacity = 10){_array = (DataType*)malloc(capacity * sizeof(DataType));if (nullptr == _array){perror("malloc申請空間失敗");return;}_size = 0;_capacity = capacity;}void Push(const DataType& data){// CheckCapacity();_array[_size] = data;_size++;}~Stack(){if (_array){free(_array);_array = nullptr;_capacity = 0;_size = 0;}}
private:DataType* _array;size_t _size;size_t _capacity;
};
int main()
{Stack s1;s1.Push(1);s1.Push(2);s1.Push(3);s1.Push(4);Stack s2;s2 = s1;return 0;
}

我們運行會中斷

注意:如果類中未涉及到資源管理,賦值運算符是否實現都可以;一旦涉及到資源管理則必
須要實現。

4.4前置++和后置++的重載

class Date
{
public :
Date ( int year = 1900 , int month = 1 , int day = 1 )
{
_year = year ;
_month = month ;
_day = day ;
}
// 前置 ++ :返回 +1 之后的結果
// 注意: this 指向的對象函數結束后不會銷毀,故以引用方式返回提高效率
Date & operator ++ ()
{
_day += 1 ;
return * this ;
}
// 后置 ++
// 前置 ++ 和后置 ++ 都是一元運算符,為了讓前置 ++ 與后置 ++ 形成能正確重載
// C++ 規定:后置 ++ 重載時多增加一個 int 類型的參數,但調用函數時該參數不用傳遞,編譯器
自動傳遞
// 注意:后置 ++ 是先使用后 +1 ,因此需要返回 +1 之前的舊值,故需在實現時需要先將 this 保存
一份,然后給 this+1
// ? ? ? temp 是臨時對象,因此只能以值的方式返回,不能返回引用
Date operator ++ ( int )
{
Date temp ( * this );
_day += 1 ;
return temp ;
}
private :
int _year ;
int _month ;
int _day ;
};
int main ()
{
Date d ;
Date d1 ( 2022 , 1 , 13 );
d = d1 ++ ; ? ? // d: 2022,1,13 ? d1:2022,1,14
d = ++ d1 ; ? ? // d: 2022,1,15 ? d1:2022,1,15
return 0 ;
}

5.日期類的實現

為了檢驗這幾節的學習效果,如果可以手搓日期類就代表掌握了,讀者朋友可以參考并實現,以助于更好掌握該部分知識

#define _CRT_SECURE_NO_WARNINGS 1
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
#include<assert.h>
class Date{public:// 獲取某年某月的天數int GetMonthDay(int year, int month){assert(month > 0 && month < 13);static int monthday[13] = { -1,31,28,31,30,31,30,31,31,30,31,30,31 };if (month == 2 && (year % 4 == 0 && year % 100 != 0) || year % 400 == 0){return 29;}else{return monthday[month];}}// 全缺省的構造函數Date(int year, int month, int day){_year = year;_month = month;_day = day;}// 拷貝構造函數// d2(d1)Date(const Date& d){_year = d._year;_month = d._month;_day = d._day;}// 賦值運算符重載// d2 = d3 -> d2.operator=(&d2, d3)Date& operator=(const Date& d){if (this != &d){_year = d._year;_month = d._month;_day = d._day;}return *this;}// 析構函數~Date(){_year = 0;_month = 0;_day = 0;}// 日期+=天數Date& operator+=(int day){if (day < 0){return*this -= -day;}_day += day;while (_day > GetMonthDay(_year, _month)){_day = _day - GetMonthDay(_year, _month);++_month;if (_month == 13){_month = 1;}}return*this;}// 日期+天數Date operator+(int day){Date tmp = *this;tmp += day;return tmp;}// 日期-天數Date operator-(int day){Date tmp = *this;tmp -= day;return tmp;}// 日期-=天數Date& operator-=(int day){if (day < 0){return *this += -day;}_day -= day;while (_day <= 0){--_month;if (_month == 0){_month = 12;_year--;}_day += GetMonthDay(_year, _month);}return *this;}// 前置++Date& operator++(){*this += 1;return*this;}// 后置++Date operator++(int){Date tmp(*this);*this += 1;return tmp;}// 后置--Date operator--(int){Date tmp(*this);*this -= 1;return tmp;}// 前置--Date& operator--(){*this -= 1;return*this;}// >運算符重載bool operator>(const Date& d){if (_year > d._year){return true;}else if (_year == d._year){if (_month > d._month){return true;}else if (_month == d._month){return _day > d._day;}}return false;}// ==運算符重載bool operator==(const Date& d){return _year == d._year && _month == d._month && _day == d._day;}// >=運算符重載bool operator >= (const Date& d){return *this > d || *this == d;}// <運算符重載bool operator < (const Date& d){return !(*this >= d);}// <=運算符重載bool operator <= (const Date& d){return !(*this > d);}// !=運算符重載bool operator != (const Date& d){return !(*this == d);}// 日期-日期 返回天數int operator-(const Date& d);void Print(){cout << _year << "年" << _month << "月" << _day << "日" << endl;}private:int _year;int _month;int _day;};
int main()
{Date d1(2025, 12, 25);d1 -= 600;d1.Print();return 0;
}
7.const 成員
const 修飾的 成員函數 稱之為 const 成員函數 const 修飾類成員函數,實際修飾該成員函數
隱含的 this 指針 ,表明在該成員函數中 不能對類的任何成員進行修改。
class Date
{
public:Date(int year, int month, int day){_year = year;_month = month;_day = day;}void Print(){cout << "Print()" << endl;cout << "year:" << _year << endl;cout << "month:" << _month << endl;cout << "day:" << _day << endl << endl;}void Print() const{cout << "Print()const" << endl;cout << "year:" << _year << endl;cout << "month:" << _month << endl;cout << "day:" << _day << endl << endl;}
private:int _year; // 年int _month; // 月int _day; // 日
};
void Test()
{Date d1(2022,1,13);d1.Print();const Date d2(2022,1,13);d2.Print();
}
請思考下面的幾個問題:
1. const 對象可以調用非 const 成員函數嗎?
2. const 對象可以調用 const 成員函數嗎?
3. const 成員函數內可以調用其它的非 const 成員函數嗎?
4. const 成員函數內可以調用其它的 const 成員函數嗎?
注意:const不能修飾+=,-=,因為會使-=,+=無法修改,因此函數中需要修改成員的都不能用const
8. 取地址及 const 取地址操作符重載
這兩個默認成員函數一般不用重新定義 ,編譯器默認會生成。
class Date
{
public:Date* operator&(){return this;}const Date* operator&()const{return this;}
private:int _year; // 年int _month; // 月int _day; // 日
};
這兩個運算符一般不需要重載,使用編譯器生成的默認取地址的重載即可,只有特殊情況,才需
要重載,比如 想讓別人獲取到指定的內容!

最后,感謝大家的觀看!

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

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

相關文章

Python vs MATLAB:選擇深度學習的首選編程語言

Python vs MATLAB&#xff1a;選擇深度學習的首選編程語言 在深度學習領域&#xff0c;編程語言的選擇對于初學者的學習路徑和未來的職業發展至關重要。目前&#xff0c;Python和MATLAB都是進行科學計算和數據分析的流行工具&#xff0c;但它們在深度學習社區中的應用和受歡迎…

linux程序分析命令(一)

linux程序分析命令(一) **ldd&#xff1a;**用于打印共享庫依賴。這個命令會顯示出一個可執行文件所依賴的所有共享庫&#xff08;動態鏈接庫&#xff09;&#xff0c;這對于解決運行時庫依賴問題非常有用。**nm&#xff1a;**用于列出對象文件的符號表。這個命令可以顯示出定…

什么事防抖和節流,有什么區別,如何實現

防抖和節流&#xff0c;本質上是優化高頻率執行代碼的一種手段&#xff0c;比如&#xff1a;resize、scroll、keypress、mousemove這些事件在觸發的時候&#xff0c;會不斷調用綁定在事件上的回調函數&#xff0c;這樣極大浪費資源&#xff0c;降低前端性能。 為了優化體驗&am…

ipa 分區算法分析,圖解

參考 Room Segmentation: Survey, Implementation, and Analysis. 分區算法調查&#xff0c;實現以及評估對比 相關論文 分區算法 New Brooms Sweep Clean - An Autonomous Robotic Cleaning Assistant for Professional Office Cleaning 形態分割 Interactive SLAM using …

函數原型(Function Prototype)、函數定義(Function Definition)和函數聲明(Function Declaration)

函數原型&#xff08;Function Prototype&#xff09;、函數定義&#xff08;Function Definition&#xff09;和函數聲明&#xff08;Function Declaration&#xff09;在C和C等編程語言中扮演著不同的角色&#xff0c;但它們有時在概念上可能會有些重疊。下面是它們之間的主要…

NOR FLASH介紹

參考 http://t.csdnimg.cn/gHcrG 一、NOR FLASH簡介 XIP技術:https://blog.csdn.net/ffdia/article/details/87437872?fromshareblogdetail NOR Flash 和 NAND Flash 的特點和應用舉例&#xff1a; NOR Flash&#xff1a; 特點&#xff1a; 支持隨機訪問&#xff0c;可以直接…

QT作業4

1、思維導圖 2、使用定時器完成鬧鐘 頭文件&#xff1a; #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QLineEdit> #include <QLabel> #include <QPushButton> #include <QTextEdit> #include <QDebug> #include <…

收集郵票C++題目【概率期望DP+數學推導】

題意 Description 有 n n n 種不同的郵票&#xff0c;皮皮想收集所有種類的郵票。唯一的收集方法是到同學凡凡那里購買&#xff0c;每次只能買一張&#xff0c;并且 買到的郵票究竟是 n n n 種郵票中的哪一種是等概率的&#xff0c;概率均為 1 n \frac{1}{n} n1?。但是由…

【elasticsearch】慢查詢替代查詢審計的嘗試

【elasticsearch】慢查詢替代查詢審計的嘗試 使用了es有兩年了&#xff0c;突然發現一個&#xff0c;es沒有查詢審計日志&#xff0c;某個用戶查詢了某個索引的審計。 找了官方文檔和社區的回復都是說使用slow log替代慢查詢。 嘗試一下。 參考鏈接1&#xff1a;https://discus…

Py深度學習基礎|關于Batch Normalization

1. 為什么需要Batch Normalization 通常我們會在輸入層進行數據的標準化處理&#xff0c;這是為了讓模型學習到更好的特征。同樣&#xff0c;在模型的中間層我們也可以進行normalize。在神經網絡中, 數據分布對訓練會產生影響。 比如我們使用tanh作為激活函數&#xff0c;當輸入…

Baidu Comate智能編碼助手:AI編程時代提升效率的好幫手

目錄 寫在前面一、如何安裝二、如何使用場景需求體驗步驟 三、AI 編程實戰指令功能插件功能知識庫功能 四、問題建議五、體驗總結&#x1f680;寫在最后 寫在前面 Baidu Comate 是基于文心大模型的 AI編程工具&#xff0c;它結合百度積累多年的編程現場大數據和外部優秀開源數據…

MySQL中的多表查詢

數據庫設計范式(范例) 好的數據庫設計&#xff0c;事倍功半&#xff0c;不會有歧義 第一范式&#xff1a;列保證原子性&#xff08;列不可再分解&#xff09; 聯系方式&#xff1a;電話&#xff0c;微信&#xff0c;QQ&#xff0c;郵箱 這些都不可分解 第二范式&#xff1a;要…

annaconda詳細解讀換源文件

annaconda換源詳細解讀文件 annaconda換源詳細解讀文件 annaconda換源詳細解讀文件 #踩坑/annaconda換源詳細解讀通道問題 如何準確使用國內源高效安裝GPU版本的Pytorch - 知乎 文件中的custom通道&#xff0c;需要自己手動添加到默認通道里面&#xff0c;記得后面更上/包名…

在xAnyLabeling中加載自己訓練的yolov8s-obb模型進行半自動化標注

任務思路&#xff1a; 先使用xAnyLabeling標注一部分樣本&#xff0c;訓練出v1版本的yolov8-obb模型&#xff0c;然后加載yolov8-obb模型到xAnyLabeling中對其余樣本進行半自動化標注。節省工作量。 任務流程&#xff1a; 1.準備xAnyLabeling標注工具 下載代碼&#xff0c;…

Redis系列-3 Redis緩存問題

1.緩存的作用 數據庫(如Mysql)的持久化特點帶來了較低的性能&#xff0c;高并發的場景下&#xff0c;連接池很快被耗盡而出現宕機或DOS&#xff0c;無法繼續對外提供服務。相對于數據庫的硬盤IO&#xff0c;緩存中間件基于內存進行讀寫&#xff0c;從而具備較大的吞吐量和高并…

SpringBoot:注解詳解

RequestMapping 注解在類上:表示該類中所有響應請求的方法都以此地址為父路徑 value&#xff08;path&#xff09; 指定請求的實際訪問地址&#xff0c;默認RequestMapping(“url”)的值url即為value的值。指定的地址可以是 URI Template 模式。 method 指定請求的method類型…

數據結構(四)——二叉樹和堆(下)

制作不易&#xff0c;三連支持一下唄&#xff01;&#xff01;&#xff01; 文章目錄 前言一、二叉樹鏈式結構的實現總結 前言 這篇博客我們將來了解普通二叉樹的實現和應用&#xff0c;對大家之前分治和遞歸的理解有所挑戰。 一、二叉樹鏈式結構的實現 1.前置說明 在學習二叉…

Java入門——繼承和多態(上)

包 包是組織類的一種方式. 使用包的主要目的是保證類的唯一性. 例如, 你在代碼中寫了一個 Test 類. 然后你的舍友也可能寫一個 Test 類. 如果出現兩個同名的類, 就會沖突, 導致 代碼不能編譯通過. 導入包中的類 Java 中已經提供了很多現成的類供我們使用. 例如 public cla…

服裝店會員管理系統結合小程序商城幫你挖掘出潛在客戶

在現代社會&#xff0c;隨著科技的不斷進步和人們消費習慣的變化&#xff0c;傳統的服裝店已經不再能夠滿足消費者的需求。為了更好地服務客戶&#xff0c;提升銷售業績&#xff0c;許多服裝店開始引入會員管理系統&#xff0c;并結合小程序商城&#xff0c;實現線上線下的無縫…

LeetCode-2079. 給植物澆水【數組 模擬】

LeetCode-2079. 給植物澆水【數組 模擬】 題目描述&#xff1a;解題思路一&#xff1a;簡單的模擬題&#xff0c;初始化為0&#xff0c;考慮先不澆灌每一個植物解題思路二&#xff1a;初始化為n&#xff0c;考慮每一個植物需要澆灌解題思路三&#xff1a;0 題目描述&#xff1a…