C-特性和新特性

C++特性和新特性

C++11

C++11是C++編程語言的一個重要標準版本,是C++98標準發布后13年來的第一次重大修正,它引入了許多新特性和改進,極大地增強了C++語言的表達能力和開發效率。

C++11是C++編程語言的一個重要標準版本,由國際標準化組織(ISO)和國際電工委員會(IEC)旗下的C++標準委員會(ISO/IEC JTC1/SC22/WG21)于2011年8月12日公布,并于2011年9月正式出版,其標準文件號為ISO/IEC 14882:2011。C++11是C++98標準發布后13年來的第一次重大修正,它引入了許多新特性和改進,極大地增強了C++語言的表達能力和開發效率。以下是對C++11的一些主要特性和改進的歸納:

核心語言的新機能
自動類型推導(auto)

C++11引入了auto關鍵字,用于自動推導變量的類型,使得代碼更加簡潔,特別是在處理復雜類型或模板類型時。

#include <iostream>  
#include <vector>  int main() {  // 使用auto推導vector<int>類型  auto myVector = std::vector<int>{1, 2, 3, 4, 5};  // 遍歷vector  for(auto it = myVector.begin(); it != myVector.end(); ++it) {  std::cout << *it << std::endl;  }  // 推導函數返回類型  auto result = myVector.size(); // result的類型是std::vector<int>::size_type,通常是unsigned int  return 0;  
}
decltype

與auto類似,但decltype用于推導表達式的類型,適用于auto無法使用的場景。

#include <iostream>  int main() {  int x = 5;  // 使用decltype獲取x的類型,并聲明同類型的變量y  decltype(x) y = x;  // 也可以用于復雜表達式  int a = 1, b = 2;  decltype(a + b) c = a + b; // c的類型是int  // 引用類型  int& ref = x;  decltype(ref) anotherRef = y; // anotherRef也是int&類型  // 注意,decltype(表達式)的結果取決于表達式的形式  decltype((x)) wholeX = x; // wholeX是int&,因為表達式(x)是左值  return 0;  
}
右值引用和移動語義

引入了右值引用(T&&)和移動語義,允許臨時對象(右值)的資源被“竊取”以進行高效的資源轉移,避免了不必要的拷貝操作。

  • 右值引用:右值引用是C++11中引入的一個關鍵特性,它允許程序員顯式地將一個表達式標記為右值,從而可以利用移動語義進行優化。在C++中,每個表達式都可以被分類為左值或右值。左值是指那些可以取地址的表達式,如變量、數組元素等,而右值則是指那些不能取地址的表達式,如字面量、臨時變量、表達式求值結果等。右值引用就是用來引用這些右值的類型,其語法是在變量名前添加兩個連續的“&”符號,如“int&&”。
int&& rvalueRef = 10; // 正確:10是右值,可以被右值引用綁定  
int x = 10;  
int&& rvalueRef2 = std::move(x); // 正確:使用std::move將x轉換為右值
  • 移動語義:移動語義是C++11中引入的一種新的語言特性,旨在提高程序的性能和資源管理效率。其核心概念在于允許對象間資源的轉移,而非傳統的拷貝操作。移動語義通過右值引用和移動構造函數(以及移動賦值運算符)實現了資源的所有權從一個對象到另一個對象的轉移,從而避免了不必要的復制操作。
  • 移動構造函數:接收一個右值引用參數,并將其資源“移動”到新的對象中,而不是復制這些資源。移動構造函數的定義形式為ClassName(ClassName&& other);
  • 移動賦值函數:用于將一個對象的資源轉移給另一個已經存在的對象,其定義形式通常為ClassName& operator=(ClassName&& other);
class MyClass {  
public:  MyClass(int* data) : ptr(data) {}  MyClass(MyClass&& other) noexcept : ptr(other.ptr) {  other.ptr = nullptr; // 確保原對象不再擁有資源  }  MyClass& operator=(MyClass&& other) noexcept {  if (this != &other) {  delete[] ptr; // 釋放原資源  ptr = other.ptr;  other.ptr = nullptr; // 確保原對象不再擁有資源  }  return *this;  }  ~MyClass() { delete[] ptr; }  private:  int* ptr;  
};  MyClass createMyClass() {  return MyClass(new int[100]); // 返回臨時對象,將觸發移動語義  
}  MyClass obj = createMyClass(); // 這里將調用移動構造函數
統一的初始化

C++11引入了統一的初始化語法({}),使得所有類型的對象都可以使用相同的初始化方式。通過大括號{}std::initializer_list提供了更加靈活、安全、直觀的初始化方法。

  1. 使用大括號{}直接初始化
    • 對于基本數據類型:int a{10};
    • 對于數組:int arr[3]{1, 2, 3}; 或者 int arr[3] = {1, 2, 3};(注意,這里=并不是傳統意義上的拷貝初始化,而是C++允許的一種簡寫形式,仍然屬于統一初始化)
    • 對于結構體和類對象:struct Point{int x, y;} p{1, 2};
    • 對于容器:std::vector<int> vec{1, 2, 3};
  2. 使用std::initializer_list
    • 在C++11中,許多容器(如std::vectorstd::map等)都增加了接受std::initializer_list作為參數的構造函數,使得容器初始化更加方便。
    • std::initializer_list是一個輕量級的、可以容納固定數量元素的容器,它在初始化時自動生成,并在初始化結束后銷毀。
Lambda表達式

提供了一種定義匿名函數對象的方式,使得編寫回調函數等更加簡潔方便。Lambda 表達式特別適用于需要函數對象但又不想正式命名一個函數的場景,比如作為算法(如 std::sort)的參數,或者在需要回調函數的地方。

[capture](parameters) mutable -> return_type {  // 函數體  
}
  • 捕獲列表[capture]):指定哪些外部變量在 lambda 表達式內部是可見的。如果省略捕獲列表,則 lambda 表達式不能訪問任何外部變量。捕獲列表可以是值捕獲(通過拷貝)或引用捕獲(通過引用)。
  • 參數列表(parameters)):與普通函數的參數列表相同,定義了 lambda 表達式的參數。如果 lambda 表達式不接受任何參數,則可以省略參數列表。
  • mutable 關鍵字(可選):允許在 lambda 表達式體內修改被捕獲的變量的值(如果它們是通過值捕獲的)。默認情況下,這些變量在 lambda 表達式內是不可變的。
  • 返回類型-> return_type):指定 lambda 表達式的返回類型。如果 lambda 表達式體只包含一個返回語句,并且編譯器可以推導出返回類型,則可以省略返回類型。
  • 函數體:定義了 lambda 表達式的操作。
  • 一個計算兩數之和的簡單例子:
#include <iostream>  
#include <algorithm>  
#include <vector>  int main() {  int a = 10, b = 20;  // 定義一個 lambda 表達式,計算兩個整數的和  auto sum = [](int x, int y) { return x + y; };  // 使用 lambda 表達式  std::cout << "The sum is " << sum(a, b) << std::endl;  // 使用 lambda 表達式作為 std::sort 的比較函數  std::vector<int> vec = {4, 1, 3, 5, 2};  std::sort(vec.begin(), vec.end(), [](int x, int y) { return x < y; });  for (int n : vec) {  std::cout << n << ' ';  }  std::cout << std::endl;  return 0;  
}
標準庫的擴展
智能指針

C++11標準庫增加了shared_ptr、unique_ptr和weak_ptr等智能指針,用于自動管理動態分配的內存,減少內存泄漏的風險。

  1. unique_ptr
    • 獨占式智能指針,確保只有一個指針可以指向資源。
    • 通過std::move()函數可以轉移資源的所有權。
#include <iostream>  
#include <memory>  class MyClass {  
public:  MyClass(int value) : value_(value) {}  void print() const { std::cout << "Value: " << value_ << std::endl; }  private:  int value_;  
};  int main() {  // 創建一個 unique_ptr 指向 MyClass 的實例  std::unique_ptr<MyClass> ptr = std::make_unique<MyClass>(10);  // 使用 ptr  ptr->print();  // 當 ptr 離開作用域時,它指向的 MyClass 實例將被自動銷毀  return 0;  
}
  1. shared_ptr
    • 共享式智能指針,允許多個指針共享同一個資源。
    • 采用引用計數機制,當所有shared_ptr對象都不再需要該資源時,資源會自動被銷毀。
//Myclass同上
int main() {  // 創建兩個 shared_ptr 指向同一個 MyClass 實例  std::shared_ptr<MyClass> ptr1 = std::make_shared<MyClass>(20);  std::shared_ptr<MyClass> ptr2 = ptr1; // ptr2 和 ptr1 共享所有權  // 使用 ptr1 和 ptr2  ptr1->print();  ptr2->print();  // 當 ptr1 和 ptr2 都離開作用域時,MyClass 實例將被銷毀  return 0;  
}
  1. weak_ptr
    • 弱引用智能指針,用于輔助shared_ptr工作,不增加資源的引用計數。
    • 當所有的shared_ptr對象都不再需要該資源時,weak_ptr對象會自動失效。
//Myclass同上
int main() {  // 創建一個 shared_ptr 和一個 weak_ptr  std::shared_ptr<MyClass> ptr = std::make_shared<MyClass>(30);  std::weak_ptr<MyClass> weakPtr = ptr;  // 使用 ptr  ptr->print();  // 嘗試通過 weakPtr 訪問資源,需要先鎖定 weakPtr  if (auto lockedPtr = weakPtr.lock()) {  lockedPtr->print();  } else {  std::cout << "weak_ptr is expired!" << std::endl;  }  // 當 ptr 離開作用域時,MyClass 實例將被銷毀  // weakPtr 將自動變為過期狀態  return 0;  
}
無序容器

新增了unordered_map和unordered_set等基于哈希表的容器,提供了比原有map和set更高的查找效率。點擊了解更多容器知識:STL標準模板庫容器操作集合-CSDN博客

  1. std::unordered_map:存儲鍵值對,其中每個鍵都是唯一的。鍵和值可以是任何可復制且可賦值的類型。
  2. std::unordered_multimap:與unordered_map類似,但允許鍵重復。
  3. std::unordered_set:只存儲鍵的集合,鍵是唯一的。
  4. std::unordered_multiset:與unordered_set類似,但允許鍵重復。
正則表達式

標準庫增加了對正則表達式的支持,使得字符串處理更加靈活和強大。從C++11開始,C++標準庫引入了<regex>頭文件,提供了對正則表達式的支持。C++中的正則表達式類和相關函數主要包括:

  1. std::regex:定義包含正則表達式的對象。
  2. std::smatchstd::cmatch:定義保存匹配結果的對象,分別用于string類型和char*類型的字符串。
  3. 常用正則匹配函數
    • std::regex_match:判斷整個目標字符串是否與正則表達式完全匹配。
    • std::regex_search:在目標字符串中搜索與正則表達式匹配的第一個子字符串。
    • std::regex_replace:用指定的字符串替換與正則表達式匹配的部分。
#include <iostream>  
#include <regex>  
#include <string>  int main() {  std::string s = "hello, world!";  std::regex e("\\bhello\\b"); // 匹配單詞"hello"  if (std::regex_search(s, e)) {  std::cout << "Match found!" << std::endl;  } else {  std::cout << "No match." << std::endl;  }  // 替換匹配到的內容  std::string replaced = std::regex_replace(s, e, "Hi");  std::cout << replaced << std::endl; // 輸出: "Hi, world!"  return 0;  
}
線程支持

C++11首次在標準庫中引入了線程支持,包括線程(std::thread)、互斥鎖(std::mutex)、條件變量(std::condition_variable)等,使得C++能夠更方便地進行多線程編程。以下是C++11中線程支持的主要特點:

  1. std::thread類
    • std::thread是C++11中用于表示線程的類。通過創建std::thread的實例并傳遞給它一個可調用對象(如函數、lambda表達式、函數對象等),可以啟動一個新的線程來執行該可調用對象。
    • std::thread的構造函數有多種重載形式,允許傳遞不同數量和類型的參數給線程函數。
  2. 線程控制
    • join():等待線程結束。調用線程(通常是主線程)會阻塞,直到被join的線程執行完畢。join操作是線程同步的一種方式。
    • detach():分離線程,使其獨立于主線程運行。一旦線程被分離,就不能再對其執行join操作。分離后的線程在結束時會自動釋放資源。
    • joinable():檢查線程是否可以被join。如果線程已經被join或detach,或者線程對象從未與任何執行線程關聯,則joinable()返回false。
  3. 線程ID
    • 每個std::thread對象都有一個唯一的標識符,可以通過調用get_id()成員函數來獲取。這個ID可以用于區分不同的線程。
  4. 線程互斥與同步
    • C++11還引入了<mutex><condition_variable>等頭文件,提供了互斥鎖、條件變量等同步機制,用于解決多線程中的數據競爭和同步問題。
#include <iostream>  
#include <thread>  //在這個示例中,我們創建了兩個線程t1和t2,它們分別執行threadFunction函數,并傳遞不同的參數。然后,主線程通過調用join()函數等待這兩個線程結束。
void threadFunction(int n) {  for (int i = 0; i < 5; ++i) {  std::cout << "Thread: " << n << ", Count: " << i << std::endl;  }  
}  int main() {  std::thread t1(threadFunction, 1);  std::thread t2(threadFunction, 2);  // 等待兩個線程結束  t1.join();  t2.join();  return 0;  
}
其他重要特性
nullptr

引入了nullptr作為空指針的字面量,替代了原來的NULL宏,提高了代碼的安全性和可讀性。

  • nullptr 是一個特殊的關鍵字,其類型是 std::nullptr_t。這個類型只能被隱式轉換為指針類型,而不能被轉換為整數類型,從而避免了類型不匹配的問題。
  • 相比之下,NULL 通常被定義為 0((void*)0),可以隱式地轉換為任何指針類型或整數類型,這可能導致意外的類型轉換錯誤。
基于范圍的for循環

提供了一種更簡潔的遍歷容器或數組的方式,使得代碼更加簡潔易讀。

for (declaration : expression) {  // 循環體  
}
  1. 元素類型:在declaration中聲明的類型應該與容器中元素的類型相匹配,或者至少是容器中元素類型的可隱式轉換類型。
  2. 修改元素:如果你需要在循環中修改元素的值,并且這個修改對容器是可見的,你應該使用元素的引用(通過&)來聲明變量。例如:
for (int& num : nums) {  num *= 2; // 將會修改容器中的元素  
}

例子

#include <iostream>  
#include <vector>  int main() {  std::vector<int> nums = {1, 2, 3, 4, 5};  // 使用基于范圍的for循環遍歷vector  for (int num : nums) {  std::cout << num << " ";  }  return 0;  
}
變長參數模板

允許模板參數的數量在編譯時確定,為泛型編程提供了更強大的能力。(沒看懂,以后再說)

constexpr

允許在編譯時計算表達式的值,并用于常量表達式的定義,提高了程序的運行效率。使用 constexpr 可以提高程序的性能,因為它允許編譯器在編譯時進行更多的優化,而不是在運行時計算表達式的值。

  • 變量:當用于變量時,constexpr 變量必須在聲明時初始化,并且其值必須是編譯時常量。這意味著它不能依賴于運行時才能確定的值,如用戶輸入或文件讀取。
constexpr int max_value = 100; // 正確:編譯時常量  
// constexpr int x = get_value_from_user(); // 錯誤:不是編譯時常量  // 可以在編譯時計算  
constexpr int square(int x) {  return x * x;  
}  constexpr int result = square(5); // 正確:result 的值是 25,在編譯時確定
  • 函數:當用于函數時,constexpr 函數表示該函數可以在編譯時求值,但并非所有 constexpr 函數都必須在編譯時調用。如果一個 constexpr 函數在編譯時沒有被用于需要常量表達式的上下文中,它也可以像普通函數一樣在運行時被調用。
constexpr int factorial(int n) {  return n <= 1 ? 1 : n * factorial(n - 1);  
}  int main() {  constexpr int value = factorial(5); // 在編譯時計算  std::cout << "Factorial of 5 is " << factorial(10) << std::endl; // 在運行時計算  return 0;  
}
C++與Java

以下是對C++和Java更詳細的比較,包括語法、跨平臺性、性能、安全性以及各自的優勢和應用場景等方面的詳細分析:

一、語法和風格

C++

  • 面向對象:C++是一種支持面向對象的編程語言,但它也支持面向過程和泛型編程。
  • 復雜性:C++的語法相對復雜,包含指針、手動內存管理、多重繼承等特性,這使得它在學習和使用時需要更多的注意和技巧。
  • 靈活性:由于C++提供了對底層硬件的直接訪問能力,它允許開發者編寫高度優化的代碼,但同時也需要開發者對內存和資源的管理有深入的理解。

Java

  • 面向對象:Java是一種純面向對象的編程語言,所有的代碼都封裝在類中。
  • 簡潔性:Java的語法比C++更簡單、更直觀,易于學習和使用。它自動管理內存,減少了內存泄漏和指針錯誤的風險。
  • 平臺無關性:Java的“一次編寫,到處運行”特性使得它可以在任何支持Java虛擬機(JVM)的平臺上運行,無需修改代碼。
二、跨平臺性

C++

  • 跨平臺編譯:C++可以通過編寫可移植的代碼或使用跨平臺庫來實現跨平臺編譯和運行,但這需要開發者對不同的操作系統有一定的了解,并編寫相應的適配代碼。
  • 平臺依賴:在某些情況下,C++程序可能依賴于特定的操作系統或硬件特性,這限制了其跨平臺能力。

Java

  • 自動跨平臺:Java通過字節碼和Java虛擬機(JVM)實現了真正的跨平臺能力。Java程序在任何安裝了JVM的平臺上都可以運行,無需任何修改。
  • 廣泛支持:由于JVM的廣泛部署和支持,Java程序幾乎可以在所有主流操作系統上運行。
三、性能

C++

  • 高性能:C++程序通常比Java程序具有更高的性能,因為它更接近底層硬件,且提供了更多的控制。
  • 編譯型語言:C++是編譯型語言,代碼在編譯時會被轉換成機器碼,這使得它可以在運行時直接執行,減少了運行時的開銷。

Java

  • 優化性能:盡管Java在性能上不如C++,但通過即時編譯器(JIT)和其他優化技術,Java程序的性能已經非常接近甚至在某些情況下超過C++。
  • 內存管理開銷:Java的自動內存管理和垃圾回收機制雖然簡化了編程過程,但也帶來了一定的性能開銷。
四、安全性

C++

  • 潛在風險:C++的復雜性使得它更容易出現安全問題,如緩沖區溢出、內存泄漏等。開發者需要更加小心地管理資源和避免常見的編程錯誤。
  • 直接硬件訪問:C++的直接硬件訪問能力在帶來性能優勢的同時,也增加了被惡意利用的風險。

Java

  • 較高安全性:Java通過其自動內存管理、強類型檢查和運行時環境等特性提供了相對較高的安全性。
  • 沙箱模型:Java的沙箱模型限制了程序對系統資源的訪問,進一步提高了安全性。
五、優勢和應用場景

C++

  • 優勢:高性能、直接硬件訪問、豐富的庫和生態系統、多范式編程支持。
  • 應用場景:系統級編程(如操作系統、驅動程序)、游戲開發、嵌入式系統、高頻交易等。

Java

  • 優勢:跨平臺性、自動內存管理、豐富的類庫和框架、強大的社區支持。
  • 應用場景:企業級應用(如ERP、CRM)、Web開發(如Servlet、JSP)、移動應用開發(如Android)、大數據處理(如Hadoop)等。
C++和Python

C++和Python是兩種非常流行的編程語言,它們各自具有獨特的特性和優勢,適用于不同的編程場景和需求。以下是對C++和Python的詳細比較和歸納:

C++
性能與效率
  • 編譯型語言:C++是一種編譯型語言,其代碼被編譯成機器碼后直接在計算機上執行,因此執行速度通常比解釋型語言快。
  • 高效性:C++編譯生成的機器碼效率高,可以直接與硬件進行交互,適合在性能要求較高的應用中使用。
底層控制
  • 內存管理:C++允許程序員直接管理內存,包括分配和釋放內存,這提供了更大的靈活性和性能優勢,但也增加了內存泄漏和懸掛指針的風險。
  • 指針操作:C++支持指針操作,允許直接訪問內存地址,這在系統編程和嵌入式系統開發中非常有用。
面向對象編程
  • 支持面向對象編程:C++支持面向對象編程,允許使用類和對象來組織代碼,提高了代碼的可重用性和可維護性。
  • 多范式編程:除了面向對象編程外,C++還支持泛型編程和函數式編程等不同的編程范式。
標準庫與移植性
  • 豐富的標準庫:C++標準庫提供了豐富的數據結構和算法,幫助開發者更容易地實現各種功能。
  • 良好的移植性:C++編寫的程序可以在多個平臺上編譯和運行,具有很好的移植性。
復雜性與學習曲線
  • 相對復雜:C++的語法相對較為復雜,需要程序員更加關注內存管理和指針操作,因此學習曲線較陡。
  • 開發速度:由于需要手動管理內存和進行更多的底層操作,相比Python等高級語言,C++的開發速度通常較慢。
Python
簡潔易讀
  • 簡潔的語法:Python以其簡潔優美的語法而聞名,代碼量通常更少,更易于閱讀和理解。
  • 動態類型:Python是一種動態類型語言,在運行時可以根據賦值來自動推斷變量的類型,增加了代碼的靈活性。
高級特性
  • 自動內存管理:Python使用垃圾回收機制自動管理內存,開發者無需操心內存釋放的問題,這使得Python編程更加安全和簡單。
  • 支持多種編程范式:Python支持面向對象編程、函數式編程等高級特性,提供了更高的開發效率。
豐富的庫與生態系統
  • 龐大的標準庫和第三方庫:Python擁有龐大且活躍的社區,提供了豐富的第三方庫和工具,使得開發者能夠快速解決各種問題。
  • 廣泛的應用領域:Python廣泛用于Web開發、數據分析、人工智能、科學計算等領域,是人工智能領域的主要編程語言之一。
開發速度與易用性
  • 易學易用:Python的語法簡單清晰,易于學習和閱讀,適合初學者入門編程。
  • 快速開發:Python的簡潔性和豐富的庫使得開發者能夠快速編寫和測試代碼,提高開發效率。

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

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

相關文章

如何在Java中實現自定義數據結構:從頭開始

如何在Java中實現自定義數據結構&#xff1a;從頭開始 大家好&#xff0c;我是免費搭建查券返利機器人省錢賺傭金就用微賺淘客系統3.0的小編&#xff0c;也是冬天不穿秋褲&#xff0c;天冷也要風度的程序猿&#xff01;今天我們將探討如何在Java中實現自定義數據結構&#xff…

一文徹底搞懂Transformer - Input(輸入)

一、輸入嵌入&#xff08;Input Embedding&#xff09; 詞嵌入&#xff08;Word Embedding&#xff09;&#xff1a;詞嵌入是最基本的嵌入形式&#xff0c;它將詞匯表中的每個單詞映射到一個固定大小的向量上。這個向量通常是通過訓練得到的&#xff0c;能夠捕捉單詞之間的語義…

HTTP入門

入門HTTP協議 1. 原理介紹 爬蟲就是用程序模擬瀏覽器的行為&#xff0c;發送請求給服務器&#xff0c;獲取網頁的內容&#xff0c;解析網頁數據。 要學會爬蟲&#xff0c;先要了解瀏覽器是如何和服務器交流的。瀏覽器通過HTTP協議和服務器交流。 2. HTTP協議簡介 2.1…

第4篇 區塊鏈的優勢與挑戰:為什么區塊鏈如此重要?

區塊鏈聽起來像是一種高科技的魔法&#xff0c;很多人都想知道它到底是怎么回事&#xff0c;為什么會引起如此大的關注。今天&#xff0c;我們就來揭開區塊鏈的神秘面紗&#xff0c;看看它的優勢和挑戰&#xff0c;順便聊聊為什么它會變得如此重要。 優勢篇 1. 去中心化&…

【pg】去除pg數據庫字段值中的空格

如何批量去除PostgreSQL數據庫字段值中的空格 在處理數據庫中的數據時&#xff0c;經常會遇到字段值末尾帶有多余空格的問題。這些空格可能是用戶輸入錯誤或數據遷移過程中引入的&#xff0c;可能會影響數據的準確性和一致性。本文將介紹如何使用 PostgreSQL 的 SQL 語句批量去…

The Forest Enemy Pack(2D動畫角色游戲模型)

這個包包含14個適用于platformer和2d rpg游戲的動畫角色。 動畫總幀數:1785 用于動畫的所有精靈都具有透明背景,并準備有1500x1200和750x600兩種尺寸。 對于每個角色,你也可以找到具有單獨身體部位的精靈表,這樣你就可以輕松地制作自己的動畫。它們有PNG和PSD格式。 示例場…

對MVC的理解以及如何實現一個簡單的MVC

IOC 容器與 Controller&#xff1a; 在 Spring 框架中&#xff0c;所有的 Controller 都會被 Spring 的 IOC 容器管理。當應用程序啟動時&#xff0c;Spring 會掃描所有帶有 Controller 注解的類&#xff0c;并將它們作為 Bean 注冊到 IOC 容器中。 方法掃描與 Dispatcher&am…

強化學習-5 策略梯度、Actor-Critic 算法

文章目錄 1 基于價值&#xff08; value-based \text{value-based} value-based &#xff09;算法的缺點2 策略梯度算法2.1 解釋2.1.1 分母和分子相消2.1.2 對數函數的導數2.1.3 組合公式2.1.4 總結 3 REINFORCE算法4 策略梯度推導進階4.1 平穩分布4.2 基于平穩分布的策略梯度…

Python游戲腳本開發之大漠插件

自動化 文章目錄 自動化前言一、開發環境二、免注冊調用三、創建大漠對象四、注冊五、大漠功能調用六、整體代碼 前言 大漠插件是集前后臺&#xff0c;文字識別&#xff0c;圖色&#xff0c;鍵鼠&#xff0c;窗口&#xff0c;內存&#xff0c;DX&#xff0c;Call等功能于一身的…

HSP_13章 Python_魔術方法

文章目錄 P132 魔術方法1. 魔術方法的基本介紹2. 常見的魔術方法2.1 __str__2.2 __eq__2.3 其它的幾個魔術方法 P132 魔術方法 參考文檔 1. 魔術方法的基本介紹 2. 常見的魔術方法 2.1 str # 請輸出Monster[name&#xff0c;job&#xff0c;sal]對象的屬性信息 #可以根據需要…

(1, ‘[SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1124)

WARNING: Retrying (Retry(total4, connectNone, readNone, redirectNone, statusNone)) after connection broken by SSLError(SSLError(1, [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1124))): /pypi/simple/urllib3/ pip install的時候遇到這個錯誤 第一步…

競賽選題 交通目標檢測-行人車輛檢測流量計數 - 競賽選題

文章目錄 0 前言1\. 目標檢測概況1.1 什么是目標檢測&#xff1f;1.2 發展階段 2\. 行人檢測2.1 行人檢測簡介2.2 行人檢測技術難點2.3 行人檢測實現效果2.4 關鍵代碼-訓練過程 最后 0 前言 &#x1f525; 優質競賽項目系列&#xff0c;今天要分享的是 &#x1f6a9; 畢業設計…

OtterTune dead,參數調優還有DBdoctor

前言 數據庫性能調優這塊必不可少的環節是進行參數調優&#xff0c;數據庫的參數很多&#xff0c;比如Oracle甚至有上千個參數&#xff0c;如何進行參數設置非常關鍵。參數調優需要基于業務的負載模型、硬件配置等多種因素&#xff0c;好的參數調優可以讓數據庫性能整體吞吐提…

Symfony配置管理深度解析:構建可維護項目的秘訣

Symfony是一個高度靈活且功能豐富的PHP框架&#xff0c;它提供了一套強大的配置管理系統&#xff0c;使得開發者能夠輕松定制和優化應用程序的行為。本文將深入探討Symfony中的配置管理機制&#xff0c;包括配置的結構、來源、加載過程以及最佳實踐。 一、配置管理的重要性 在…

Scala類型類(Type Classes):靈活而強大的類型增強術

&#x1f31f; Scala類型類(Type Classes)&#xff1a;靈活而強大的類型增強術 在Scala編程語言中&#xff0c;類型類是一種強大的特性&#xff0c;它允許開發者以類型安全的方式擴展語言。類型類提供了一種機制&#xff0c;可以將行為與類型關聯起來&#xff0c;類似于Java中…

【筆記】Android Settings 應用設置菜單的界面代碼介紹

簡介 Settings應用中&#xff0c;提供多類設置菜單入口&#xff0c;每個菜單內又有各模塊功能的實現。 那么各個模塊基于Settings 基礎的界面Fragment去實現UI&#xff0c;層層按不同業務進行封裝繼承實現子類&#xff1a; DashboardFragmentSettingsPreferenceFragment 功…

植物大戰僵尸雜交版,最新安裝包(PC+手機+蘋果)+ 修改器+高清工具

植物大戰僵尸雜交版&#xff1a;全新游戲體驗與創意碰撞 游戲簡介 《植物大戰僵尸雜交版》是由B站知名UP主潛艇偉偉迷基于經典游戲《植物大戰僵尸》進行的一次大膽且富有創意的二次創作。這款游戲不僅保留了原版游戲的經典玩法&#xff0c;還融入了植物雜交的全新概念&#x…

Qt掃盲-QRect矩形描述類

QRect矩形描述總結 一、概述二、常用函數1. 移動類2. 屬性函數3. 判斷4. 比較計算 三、渲染三、坐標 一、概述 QRect類使用整數精度在平面中定義一個矩形。在繪圖的時候經常使用&#xff0c;作為一個二維的參數描述類。 一個矩形主要有兩個重要屬性&#xff0c;一個是坐標&am…

同步互斥與通信

目錄 一、同步與互斥的概念 二、同步與互斥并不簡單 三、各類方法的對比 一、同步與互斥的概念 一句話理解同步與互斥&#xff1a;我等你用完廁所&#xff0c;我再用廁所。 什么叫同步&#xff1f;就是&#xff1a;哎哎哎&#xff0c;我正在用廁所&#xff0c;你等會。 什…

【實戰場景】記一次UAT jvm故障排查經歷

【實戰場景】記一次UAT jvm故障排查經歷 開篇詞&#xff1a;干貨篇&#xff1a;1.查看系統資源使用情況2.將十進制進程號轉成十六進制3.使用jstack工具監視進程的垃圾回收情況4.輸出指定線程的堆內存信息5.觀察日志6.本地環境復現 總結篇&#xff1a;我是杰叔叔&#xff0c;一名…