主頁 >  其他 > 類和物件萬字總結

類和物件萬字總結

2021-12-08 08:04:08 其他

目錄

1..類的6個默認成員函式

2.建構式

3.解構式

4.復制建構式

4.深淺拷貝

6..賦值運算子多載


1..類的6個默認成員函式

如果一個類中什么成員都沒有,簡稱為空類,空類中什么都沒有嗎?并不是的,任何一個類在我們不寫的情況下,都會自動生成下面6個默認成員函式,

class Date {};

上面這個就是一個空類

2.建構式

1.對于以下的日期類:

#include<iostream>
using namespace std;
class Date
{

public: 
	void SetDate(int year, int month, int day) { 
		_year = year; _month = month; _day = day; 
   }  

void Display() {
	cout << _year << "-" << _month << "-" << _day << endl; 
} 

private: int _year;
	    int _month; 
	     int _day; 
}; 

int main() { 
	Date d1, d2;
	d1.SetDate(2018, 5, 1);
	d1.Display(); 

	d2.SetDate(2018, 7, 1);
	d2.Display();
    return 0;
}
		

對于Date類,可以通過SetDate公有的方法給物件設定內容,但是如果每次創建物件都呼叫該方法設定資訊,未免有點麻煩,那能否在物件創建時,就將資訊設定進去呢?建構式是一個特殊的成員函式,名字與類名相同,創建型別別物件時由編譯器自動呼叫,保證每個資料成員都有 一個合適的初始值,并且在物件的生命周期內只呼叫一次,

2.建構式的特性:

建構式是特殊的成員函式,需要注意的是,建構式的雖然名稱叫構造,但是需要注意的是建構式的主要任務并不是開空間創建物件,而是初始化物件,

#include<iostream>
using namespace std;
class Date{

public: 
	// 1.無參建構式 
	Date () {}  
	// 2.帶參建構式
  Date (int year, int month , int day ) { 
  _year = year ; 
  _month = month ;
  _day = day ; 
}
private :
	int _year=0 ; 
	int _month=0 ; 
	int _day=0;
};
void TestDate() {
	Date d1; 
	// 呼叫無參建構式 Date d2 (2015, 1, 1); 
	// 呼叫帶參的建構式 
	// 注意:如果通過無參建構式創建物件時,物件后面不用跟括號,否則就成了函式宣告
	// 以下代碼的函式:宣告了d3函式,該函式無參,回傳一個日期型別的物件 Date d3(); 
}

int main() {
	TestDate();
	return 0;
}

5. 如果類中沒有顯式定義建構式,則C++編譯器會自動生成一個無參的默認建構式,一旦用戶顯式定義編譯器將不再生成,

#include<iostream>
using namespace std;
class Date{

public:  // 如果用戶顯式定義了建構式,編譯器將不再生成 
/*Date(int year, int month, int day) {
	_year = year; 
	_month = month;
	_day = day;
} */
private: 
	int _year; 
	int _month;
	int _day;
};
void Test() {
	Date d;// 沒有定義建構式,物件也可以創建成功,因此此處呼叫的是編譯器生成的默認建構式
}
int main() {
	Test();
	return 0;
}

6. 無參的建構式和全預設的建構式都稱為默認建構式,并且默認建構式只能有一個,注意:無參建構式、全預設建構式、我們沒寫編譯器默認生成的建構式,都可以認為是默認成員函式,

#include<iostream>
using namespace std;
// 默認建構式
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;
}
int main() {
	Test();
}

顯然是不能夠通過編譯的

7.默認建構式的呼叫時機:

當不使用任何初始值定義一個類的非靜態變數時,會呼叫該類的默認建構式

A a;

此時,會呼叫類A的默認建構式如果類中沒有顯式地定義默認建構式,則C++編譯器會為其創造一個合成的默認建構式,如果類中已經定義了其他格式的建構式,此時C++編譯器不會再為其合成默認建構式,所以,如果此時類A的定義為

class A {
public:
  A(int i){}
};

此時,程式會報錯,報錯資訊為“error C2512: “A”: 沒有合適的默認建構式可用”這與上面那個例子是相同的

當類B含有類A的物件,并且使用類B的默認建構式時,會呼叫類A的默認建構式

class A {
  public:
    
};
 
class B {
  A m_a;
};

類本身含有類的物件且沒有在建構式中顯式初始化該物件時

class A {
  public:
   
};
 
class B {
  public:
    B(int i){
}
    A m_a;
};

8.有參建構式的三種呼叫方法

#include<iostream>
using namespace std;
class Test
{
public:

    //帶引數的建構式

    Test(int a)
    {

        cout << "Test(a)" << endl;

    }

    Test(int a, int b)
    {

        cout << "Test(a,b)" << endl;

    }
private:
    int a;
    int b;

};

int main()

{

    //1. 括號法:C++編譯器呼叫有參建構式
    Test t1(10);

    //2. 等號法:C++編譯器呼叫有參建構式
    Test t2 = (20, 10);

      //3. 建構式法:手動直接呼叫建構式//Test(30)這是一個匿名物件
       Test t3 = Test(30);

    return 0;
}

9.成員變數的命名風格

一般我們會在成員變數的前面加一個_ 我們來看一下下面這個代碼:

// 我們看看這個函式,是不是很僵硬?
class Date{public: Date(int year) 
{ // 這里的year到底是成員變數,還是函式形參? 
	year = year; //雖然此處我們可以用this指標來區別但還是建議使用下面這種方式
}
private: 
int year;
};

class Date {
				
public: 
	Date(int year) {
	_year = year;
}

private:
	int _year;
};


// 或者這樣,
class Date {
public:
	Date(int year)
	{
		m_year = year;
	}
private:
	int m_year;
};

3.解構式

1.前面通過建構式的學習,我們知道一個物件時怎么來的,那一個物件又是怎么沒呢的?解構式:與建構式功能相反,解構式不是完成物件的銷毀,區域物件銷毀作業是由編譯器完成的,而物件在銷毀時會自動呼叫解構式,完成類的一些資源清理作業

2.解構式物件消亡時即自動被呼叫,可以定義解構式來在物件消亡前做善后作業,比如釋放分配的空間等,
如果定義類時沒寫解構式,則編譯器生成預設解構式,預設解構式什么也不做,如果定義了解構式,則編譯器不生成預設解構式,

2.解構式的特性:

解構式是特殊的成員函式

特性如下:

1. 解構式名是在類名前加上字符 ~,

2. 無引數無回傳值,

3. 一個類有且只有一個解構式,若未顯式定義,系統會自動生成默認的解構式,

4. 物件生命周期結束時,C++編譯系統系統自動呼叫解構式

5.如果顯示定義了解構式那么編譯器將不在生成

如果我們需要在建構式里面干一些其他的事情則我們需要手動的寫解構式

#include<stdlib.h>
#include<assert.h>
#include<iostream>
typedef int DataType;
class SeqList {
public:
	SeqList(int capacity = 10) {
		_pData = (DataType*)malloc(capacity * sizeof(DataType));
		assert(_pData);
		_size = 0;
		_capacity = capacity;
	}
	~SeqList() {
		if (_pData) {
			free(_pData);
		}// 釋放堆上的空間 _pData = NULL; // 將指標置為空 
   _capacity = 0;
     _size = 0;
	}
private:
	int* _pData;
	size_t _size; 
	size_t _capacity;
};

3.在創建一類物件陣列時,對于每一個陣列中的元素都會執行預設的建構式,同樣物件聲生命周期結束時陣列中的每個元素的解構式都會被呼叫

#include<iostream>
using namespace std;
unsigned int count1 = 0;
class A
{
public:
    A ( )
    {
        i = ++count1;
        cout << "Creating A " << i <<endl;
    }
    ~A ( )
    {
        cout << "A Destructor called " << i <<endl;
    }
private :
    int i;
};
int main( )
{
    A arr[3];  // 物件陣列
    return 0;
}

運行結果:

為什么解構式的呼叫和建構式相反了這是因為堆疊的性質:先進后出

4.解構式的呼叫時機:

如果出現以下幾種情況,程式就會執行解構式:
(1)如果在一個函式中定義了一個物件(它是自動區域物件),當這個函式被呼叫結束時,物件應該釋放,在物件釋放前自動執行解構式,
(2)static區域物件在函式呼叫結束時物件并不釋放,因此也不呼叫解構式,只在main函式結束或呼叫exit函式結束程式時,才呼叫static區域物件的解構式,
(3)如果定義了一個全域物件,則在程式的流程離開其作用域時(如main函式結束或呼叫exit函式) 時,呼叫該全域物件的解構式,
(4)如果用new運算子動態地建立了一個物件,當用delete運算子釋放該物件時,先呼叫該物件的解構式,
(5)呼叫復制建構式后,

#include <iostream>
using namespace std;
class CMyclass
{
public:
    ~CMyclass()
    {
        cout << "destructor" << endl;
    }
};
CMyclass obj;
CMyclass fun(CMyclass sobj)
{
    return sobj;   //函式呼叫回傳時生成臨時物件回傳
}
int  main()
{
    obj = fun(obj);  //函式呼叫的回傳值(臨時物件)被用過后,該臨時物件解構式被呼叫
}

運行結果:

destructor // 形參和實參結合,會呼叫復制建構式,臨時物件析構
destructor // return sobj函式呼叫回傳,會呼叫復制建構式,臨時物件析構
destructor // obj物件析構

建構式和解構式總結:

建構式的呼叫:
(1)全域變數:程式運行前;
(2)函式中靜態變數:函式開始前;
(3)函式引數:函式開始前;
(4)函式回傳值:函式回傳前;
解構式的呼叫:
(1)全域變數:程式結束前;
(2)main中變數:main結束前;
(3)函式中靜態變數:程式結束前;
(4)函式引數:函式結束前;
(5)函式中變數:函式結束前;
(6)函式回傳值:函式回傳值被使用后;

注意:對于相同作用域和存盤類別的物件呼叫解構式和建構式的順序的呼叫次序剛好相反

3.復制建構式

1.復制建構式是一種特殊的建構式,具有一般建構式的所有特性,復制建構式創建一個新的物件,作為另一個物件的拷貝,復制建構式只含有一個形參,而且其形參是對應物件的參考,復制建構式形如 X::X( X& ), 只有一個引數即對同類物件的參考,如果沒有定義,那么編譯器生成預設復制建構式,
復制建構式的兩種原型(prototypes),以類Date為例,Date的復制建構式可以定義為如下形式:

                           Date(Date & ); 

或者:

 Date( const Date & );  

特別要注意的是:復制建構式的引數只有一個且必須使用參考傳參,使用傳值方式會引發無窮遞回呼叫 ,這是因為函式傳引數時實參是形參的一份拷貝下面我們來看這個例子:

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;
	}private: int _year; 
	int _month; 
	int _day;
};
int main() {
	Date d1; 
	Date d2(d1);
	return 0;
}

復制建構式的特性:

1. 拷貝建構式是建構式的一個多載形式,

2. 拷貝建構式的引數只有一個且必須使用參考傳參,使用傳值方式會引發無窮遞回呼叫,

3.若未顯示定義,系統生成默認的拷貝建構式, 默認的拷貝建構式物件按記憶體存盤按位元組序完成拷貝,這種拷貝我們叫做淺拷貝,或者值拷貝,

3.復制建構式的呼叫時機:、

1.一個物件需要通過另外一個物件初始化

2.一個物件以值傳遞的方式傳入函式體

3.一個物件以傳值的方式從函式回傳

下面我們來看一下例子:

1.一個物件需要通過另外一個物件初始化

#include <iostream>
using namespace std;
class Complex
{
public:
    Complex(double r, double i)
    {
        real = r;
        imag = i;
    }
    Complex(Complex& c)
    {
        real = c.real;
        imag = c.imag;
        cout << "copy constructor!" << endl;
    }
private:
    double real;
    double imag;
};
int main()
{
    Complex c1(1, 2);  //呼叫建構式Complex(double r, double i)
    Complex c2(c1);   // 呼叫復制建構式Complex( Complex & c)
    Complex c3 = c1;  // 呼叫復制建構式Complex( Complex & c)
    return 0;
}

2.一個物件以值傳遞的方式傳入函式體

函式的形參是類的物件,呼叫函式時,進行形參和實參的結合,
如果某函式有一個引數是類Complex的物件,那么該函式被呼叫時,類Complex的復制建構式將被呼叫,

復制代碼
void func(Complex c) { };
int main( )
{
    Complex c1(1,2);
    func(c1);   // Complex的復制建構式被呼叫,生成形參傳入函式
    return 0;
}

3.一個物件以傳值的方式從函式回傳

當物件傳入函式的時候被隱式呼叫以外,復制建構式在物件被函式回傳的時候也同樣的被呼叫,換句話說,你從函式回傳得到的只是物件的一份拷貝

Complex func()
{
    Complex c1(1,2);
    return c1;  // Complex的復制建構式被呼叫,函式回傳時生成臨時物件
};
int main( )
{
    func();
    return 0;
}

注意:

物件之接用等號賦值并不會呼叫復制建構式,C++中,當一個新物件創建時,會有初始化的操作,而賦值是用來修改一個已經存在的物件的值,此時沒有任何新物件被創建,初始化出現在建構式中,而賦值出現在operator=運算子函式中,編譯器會區別這兩種情況,賦值的時候呼叫多載的賦值運算子,初始化的時候呼叫復制建構式,

#include <iostream>
using namespace std;
class Complex
{
public:
    Complex(double r, double i)
    {
        real = r;
        imag = i;
    }
    Complex(Complex& c)
    {
        real = c.real;
        imag = c.imag;
        cout << "copy constructor!" << endl;
    }
private:
    double real;
    double imag;
};
int main()
{
    Complex c1(1, 2);
    Complex c2 = c1;//呼叫復制建構式
    Complex c3(3, 4);
    c3 = c1;//呼叫賦值建構式
    return 0;
}

4.匿名物件的去和留:

我們知道在C++的創建物件是一個費時,費空間的一個操作,有些固然是必不可少,但還有一些物件卻在我們不知道的情況下被創建了,通常以下三種情況會產生臨時物件:

1,以值的方式給函式傳參;

2,型別轉換;

3,函式需要回傳一個物件時;

我們先來說結論:

結論1:函式的回傳值是一個元素(復雜型別),回傳的是一個新的匿名物件(所以會呼叫匿名物件類的copy建構式)

結論2:匿名物件的去和留 .如果用匿名物件初始化 另外一個同型別的物件,匿名物件轉成有名物件 //如果用匿名物件賦值給 另外一個同型別的物件,匿名物件被析構

3.如果直接定義一個匿名物件則定義完之后它就會被析構

下面我們來看代碼:

#include <iostream>
using namespace std;
class Complex
{
public:
    Complex(double r, double i)
    {
        real = r;
        imag = i;
    }

    Complex(Complex& c)
    {
        real = c.real;
        imag = c.imag;
        cout << "copy constructor!" << endl;
    }
    ~Complex() {
        cout << "解構式呼叫" << endl;
    }

private:
    double real;
    double imag;
};
int main()
{
    Complex(1, 2);

    return 0;
}

我們通過除錯可以發現當他定義完之后執行下一句陳述句的時候就呼叫了解構式

下面我們再來看:

#include <iostream>
using namespace std;
class Complex
{
public:
    Complex(double r, double i)
    {
        cout << "建構式呼叫" << endl;
        real = r;
        imag = i;
    }

    Complex(const Complex& c)
    {
        real = c.real;
        imag = c.imag;
        cout << "復制建構式呼叫!" << endl;
    }
    ~Complex() {
        cout << "解構式呼叫" << endl;
    }

private:
    double real;
    double imag;
};
Complex test() {
    Complex a(1, 2);
    return a;
}
int main()
{
    Complex c1 = test();

    return 0;
}

此時在test里面定義了一個物件那么就會呼叫他的建構式初始化函式回傳時會生成一個匿名物件呼叫匿名物件的復制建構式,在析構a物件,而我們又恰好用一個未初始化的物件來接這個函式的回傳值那么他就會轉成有名物件也就是c1,進而在析構,

運行結果:

但如果我們用已經初始化過的物件來接那么他就會直接析構:

#include <iostream>
using namespace std;
class Complex
{
public:
    Complex(double r, double i)
    {
        cout << "建構式呼叫" << endl;
        real = r;
        imag = i;
    }

    Complex(const Complex& c)
    {
        real = c.real;
        imag = c.imag;
        cout << "復制建構式呼叫!" << endl;
    }
    ~Complex() {
        cout << "解構式呼叫" << endl;
    }

private:
    double real;
    double imag;
};
Complex test() {
    Complex a(1, 2);
    return a;
}
int main()
{
    Complex c1(2, 1);
    c1 = test();//匿名物件會直接析構掉
    return 0;
}

運行結果:

4.深淺拷貝

什么是深拷貝和淺拷貝了?

淺拷貝就是通過賦值的方式進行拷貝,那為什么說這是淺拷貝呢?就是因為賦值的方式只會把物件的表層賦值給一個新的物件,如果里面有屬性值為陣列或者物件的屬性,那么就只會拷貝到該屬性在堆疊空間的指標地址,新物件的這些屬性資料就會跟舊物件公用一份,也就是說兩個地址指向同一份資料,一個改變就會都改變,析構時也會析構兩遍從而會讓程式崩潰

深拷貝則不會出現上述問題,重新開一塊空間,拷貝資料

下面我們來看一下例子:

#include <iostream>  
using namespace std;

class Student
{
private:
	int num;
	 char* name;
public:
	Student();
	~Student();
};

Student::Student()
{
	name = new char[2]{'2','0'};
	cout << "Student" << endl;

}
Student::~Student()
{
	cout << "~Student " << (int)name << endl;
	delete name;
	name = NULL;
}

int main()
{
	{// 花括號讓s1和s2變成區域物件,方便測驗
		Student s1;
		Student s2(s1);// 復制物件
	}
	system("pause");
	return 0;
}

我們會發現此時程式崩潰了

由于s1和s2中的name同時指向了同一塊空間當我們析構的時候同一塊空間析構兩次此時程式會崩潰

此時我們就需要自己寫復制建構式重新開辟一塊新的空間:

#include <iostream>  
using namespace std;
class Student
{
public:
	Student(const char*str);

	~Student();

	Student(const Student& s){
		char* tmp = new char[strlen(s.name) + 1];
		strcpy(tmp, s.name);
		name = tmp;
	}
private:
	int num;
	char* name;
};   

Student::Student(const char*str)
{
	num = 0;
	char*tmp = new char[strlen(str) + 1];
	strcpy(tmp, str);
	name = tmp;
	cout << "Student" << endl;
}

Student::~Student()
{
	//cout << "~Student " << name << endl;
	delete []name;
	name = NULL;
}

int main()
{
	
		Student s1("hehe");
		Student s2(s1);// 復制物件
	
	return 0;
}

當我們寫了復制建構式時重寫開辟了空間此時就不會出現崩潰的問題了

總結:

1.當物件中存在指標成員時,除了在復制物件時需要考慮自定義拷貝建構式
2.當函式的引數為物件時,實參傳遞給形參的實際上是實參的一個拷貝物件,系統自動通過拷貝建構式實作;
3.當函式的回傳值為一個物件時,該物件實際上是函式內物件的一個拷貝,用于回傳函式呼叫處,

4.淺拷貝帶來問題的本質在于解構式釋放多次堆記憶體,使用std::shared_ptr,可以完美解決這個問題,

4..賦值運算子多載

C++為了增強代碼的可讀性引入了運算子多載,運算子多載是具有特殊函式名的函式,也具有其回傳值型別,函式名字以及引數串列,其回傳值型別與引數串列與普通的函式類似,函式名字為:關鍵字operator后面接需要多載的運算子符號,函式原型:回傳值型別 operator運算子(引數串列)注意:不能通過連接其他符號來創建新的運算子:比如operator@ 多載運算子必須有一個型別別或者列舉型別的運算元 用于內置型別的運算子,其含義不能改變,例如:內置的整型+,不 能改變其含義 作為類成員的多載函式時,其形參看起來比運算元數目少1成員函式的 運算子有一個默認的形參this,限定為第一個形參.* 、:: 、sizeof 、?: 、. 注意以上5個運算子不能多載,這個經常在筆試選擇題中出現

賦值運算子主要有四點:

1. 引數型別

2. 回傳值

3. 檢測是否自己給自己賦值

4. 回傳*this

5. 一個類如果沒有顯式定義賦值運算子多載,編譯器也會生成一個,完成物件按位元組序的值拷貝,(按位元組拷貝就是原封不動的拷貝過去,其實就是淺拷貝)

同樣賦值運算子也存在和賦值建構式相同的問題就是當成員變數的含有指標成員時使用編譯器自己生成的賦值運算子只是簡單的值拷貝當析構時會讓同一塊空間析構兩次從而導致程式崩潰

#include <iostream>  
using namespace std;
class Student
{
public:
	Student(const char*str);
	~Student();

	Student(const Student& s){
		char* tmp = new char[strlen(s.name) + 1];
		strcpy(tmp, s.name);
		name = tmp;
	}
private:
	int num;
	char* name;
};   

Student::Student(const char*str)
{
	num = 0;
	char*tmp = new char[strlen(str) + 1];
	strcpy(tmp, str);
	name = tmp;
	cout << "Student" << endl;
}

Student::~Student()
{
	//cout << "~Student " << name << endl;
	delete []name;
	name = NULL;
}

int main()
{
	
		Student s1("hehe");
		Student s2("helloworld");
		s1 = s2;//使用編譯器默認生成的賦值運算子

	
	return 0;
}

此時我們沒有寫operator=當前使用的時編譯器默認生成的,

運行結果:

與賦值建構式相同都是同一塊空間被析構兩次所造成的:

析構兩次:

此時我們需要自己寫operator=進行深拷貝來解決:

#include <iostream>  
using namespace std;
class Student
{
public:
	Student(const char*str);
	~Student();

	Student(const Student& s){//復制建構式深拷貝
		char* tmp = new char[strlen(s.name) + 1];
		strcpy(tmp, s.name);
		name = tmp;
	}
	Student& operator=(const Student& s) {
		if (&s != this) {
			char* tmp = new char[strlen(s.name) + 1];//開空間
			strcpy(tmp, s.name);//拷資料
			delete[]name;//釋放舊空間
			name = tmp;
		  }
		return *this;
	}

private:
	int num;
	char* name;
};   

Student::Student(const char*str)
{
	num = 0;
	char*tmp = new char[strlen(str) + 1];
	strcpy(tmp, str);
	name = tmp;
	cout << "Student" << endl;
}

Student::~Student()
{
	//cout << "~Student " << name << endl;
	delete []name;
	name = NULL;
}

int main()
{
	
		Student s1("hehe");
		Student s2("helloworld");
		s1 = s2;
	     return 0;
}

operator總結:

當類中的程式變數中含有指標變數時我們需要考慮是否要顯示的提供賦值運算子多載函式(即自定義賦值運算子多載函式):

用類 A 型別的值為類 A 的物件賦值,且類 A 的資料成員中含有指標的情況下,必須顯式提供賦值運算子多載函式

最后:

最后:🙌🙌🙌🙌
結語:對于個人來講,在編程上進行探索以及總結知識是一件有趣的時間,一個程式員,如果不喜歡編程,那么可能就失去了這份職業的樂趣,刷到我的文章的人,我希望你們可以駐足一小會,忙里偷閑的閱讀一下我的文章,可能文章的內容對你來說很簡單,(^▽^)不過文章中的每一個字都是我認真專注的見證!希望您看完之后,若是能幫到您,勞煩請您簡單動動手指鼓勵我,我必回報更大的付出~

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/375783.html

標籤:其他

上一篇:程式員求職路漫漫其修遠兮,HR眼中的你,為什么無人問津

下一篇:00后小碼農的人生感慨 —— 2021年度總結

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more