1.統一初始化特性
c98中不支持花括號進行初始化,編譯時會報錯,在11當中初始化可以通過{}括號進行統一初始化。
c98編譯報錯
c++11:?
#include <iostream>
#include <set>
#include <string>
#include <vector>int main()
{std::string str = {"111"};std::vector<std::string> vec = {"aaa","bbb","cc"};std::cout<<"str = "<<str.c_str()<<std::endl;for(auto it : vec){std::cout<<"it = "<<it.c_str()<<std::endl;}return 0;
}
輸出:
root@ubuntu:~/mySpace/other/ERT# ./a.out
str = 111
it = aaa
it = bbb
it = cc
root@ubuntu:~/mySpace/other/ERT#
2.關鍵提auto自動推導變量類型
#include <iostream>
#include <set>
#include <string>
#include <vector>
#include <map>int main()
{std::vector<std::string> vec = {"aaa","bbb","cc"};//// 直接根據實際情況推導相關變量類型for(auto it : vec){std::cout<<"it = "<<it.c_str()<<std::endl;}std::map<std::string,std::string> m = {{"11","111"},{"33","333"}};for(auto &it : m){std::cout<<"first = "<<it.first.c_str()<<" "<<"second = "<<it.second.c_str()<<std::endl;}for(auto it = m.begin();it !=m.end();++it){std::cout<<"first = "<<it->first.c_str()<<" "<<"second = "<<it->second.c_str()<<std::endl;}//c++17.c++11不支持該屬性// for (const auto& [key, value] : myMap) {// std::cout << "Key: " << key << ", Value: " << value << std::endl;// }return 0;
}
?輸出:
root@ubuntu:~/mySpace/other/ERT# ./a.out
it = aaa
it = bbb
it = cc
first = 11 second = 111
first = 33 second = 333
first = 11 second = 111
first = 33 second = 333
root@ubuntu:~/mySpace/other/ERT#
3.Lambda表達式
????????定義匿名函數對象,常用于簡化代碼,尤其是在需要傳遞函數作為參數的場景。在編譯器編譯過程中會將lambda表達式轉化成一個匿名類,并且這個匿名類重載了operator()運算符,使得可以像函數一樣被調用(類的仿制函數一樣)。
????????lamda表達式函數會自動推倒返回值無需編寫,帶返回值的寫法,如下:
語法結構表達:
// lamda表達式函數會自動推到返回值無需編寫,帶返回值的寫法auto pFunRet = []() -> std::string {std::string s("rrrrr");return s;}; std::cout<<"pFunRet() = "<<pFunRet().c_str()<<std::endl;
a.無參表達
// 無參Lamda函數表達式auto pFun = [](){std::cout<<"This is lamda fun"<<std::endl;};pFun();
輸出:
root@ubuntu:~/mySpace/other/ERT# ./a.out
This is lamda fun
root@ubuntu:~/mySpace/other/ERT#
如上表示無參數表達式,編譯器會將上述函數轉化成一個匿名累,如下,將函數轉化成匿名類,直接像函數一樣調用即可。
class __lambda_anonymous {
public:int operator()() const { std::cout<<"This is lamda fun"<<std::endl; }
};
b.有參數表達
// 帶參數auto pFunParams = [](int a,std::string s){std::cout<<"Params lamda="<<a<<"-"<<s.c_str()<<std::endl;};pFunParams(100,"LX");
輸出:? ?
root@ubuntu:~/mySpace/other/ERT# ./a.out
Params lamda=100-LX
root@ubuntu:~/mySpace/other/ERT#
?轉化匿名類形式:
class __lambda_anonymous {
public:int operator()(int a,std::string s) const { std::cout<<"Params lamda="<<a<<"-"<<s.c_str()<<std::endl; }
};
c.值捕獲
????????(值捕獲,捕獲作用域所有值,=可以替換成某個具體的值,表示單個變量捕獲)
// 值捕獲,捕獲作用域所有值,=可以替換成某個具體的值,表示單個變量捕獲int val_0 = 1;int val_2 = 2;auto pFunValue = [=](){// 值捕獲都是只讀權限,強行改變會編譯報錯,提醒read-only 'val_0'// val_0 += 1;// val_2 += 2;std::cout<<"val_0="<<val_0<<" val_2="<<val_2<<std::endl;};pFunValue();
輸出:?
root@ubuntu:~/mySpace/other/ERT# ./a.out
val_0=1 val_2=2
root@ubuntu:~/mySpace/other/ERT#
??編譯器轉化:
class __lambda_anonymous {
private:int val_0 = 1;int val_2 = 2;
public:__lambda_anonymous(int val_0,int val_2) : val_0(val_0),val_2(val_0) {} // 構造函數int operator()() const { std::cout<<"val_0="<<val_0<<" val_2="<<val_2<<std::endl;; }
};
d.mutble關鍵字
????????通過該關鍵字修飾等價于函數內部做了一份拷貝,之后再對拷貝進行操作,故而可以修改其捕獲value2,?
// 值捕獲2int value2 = 100;std::cout<<"before modify value2="<<value2<<std::endl;auto pFunValue2 = [value2]() mutable { // mutable 修飾等價于函數內部做了一份拷貝,之后再對拷貝進行操作,故而可以修改其捕獲value2,如下輸出結果展示:// before modify value2=100// value2=211// after modify value2=100value2 += 111;std::cout<<"value2="<<value2<<std::endl;};pFunValue2();std::cout<<"after modify value2="<<value2<<std::endl;
輸出:
root@ubuntu:~/mySpace/other/ERT# ./a.out
before modify value2=100
value2=211
after modify value2=100
root@ubuntu:~/mySpace/other/ERT#
編譯器匿名類:
class __lambda_unnamed {int value2 ;
public:__lambda_unnamed(int value2 ) : value2 (value2 ) {}int operator()(int value2) { // 注意:不再是constvalue2 += 111;std::cout<<"value2="<<value2<<std::endl;}
};
e.引用捕獲
????????引用修改的是捕獲的變量的本身,如下:
// 引用捕獲int quote = 100;std::cout<<"before modify quote="<<quote<<std::endl;auto pFunQuote = ["e](){quote += 20; // 引用修改的是捕獲的變量的本身,如下輸出結果://before modify quote=100//quote=120//after modify quote=120std::cout<<"quote="<<quote<<std::endl;};pFunQuote();std::cout<<"after modify quote="<<quote<<std::endl;return 0;
輸出:? ?
root@ubuntu:~/mySpace/other/ERT# ./a.out
before modify value2=100
value2=211
after modify value2=100
root@ubuntu:~/mySpace/other/ERT#
?編譯器轉換:
class __lambda_anonymous {
private:int quote; // 值捕獲的成員變量
public:__lambda_anonymous(int quote) : quote(quote) {} // 構造函數int operator()(int quote) const { quote += 1;std::cout<<"quote="<<quote<<std::endl;; }
};
4.并發編程
? ?a.創建線程:
#include <iostream>
#include <thread>void hello() {std::cout << "Hello from thread!\n";
}int main() {std::thread t(hello); // 創建線程并啟動t.join(); // 等待線程結束// 分離線程,線程結束后自動釋放資源// 注意:分離后不能再join()// t.detach(); return 0;
}
? ?b.帶參數線程處理函數
#include <iostream>
#include <thread>
void print(int id, const std::string& name) {std::cout << "ID: " << id << ", Name: " << name << "\n";
}int main() {std::thread t(print, 1, "Thread1");t.join();return 0;
}輸出:
root@ubuntu:~/mySpace/other/ERT# ./a.out
ID: 1, Name: Thread1
root@ubuntu:~/mySpace/other/ERT#
? ?c.參數引用傳遞
#include <iostream>
#include <thread>
void modify(int& x) { x *= 2;
}int main() {int x = 10;std::thread t(modify, std::ref(x));t.join();std::cout << x <<std::endl; // 輸出20return 0;
}輸出:
root@ubuntu:~/mySpace/other/ERT# ./a.out
20
root@ubuntu:~/mySpace/other/ERT#
? ?d.線程id和當前線程
#include <iostream>
#include <thread>int main() {std::thread::id main_thread_id = std::this_thread::get_id(); // 當前線程std::thread t([&]() {if (std::this_thread::get_id() == main_thread_id) {std::cout << "This is the master thread\n";} else {std::cout << "This is a son thread\n";}});t.join();return 0;
}輸出:
root@ubuntu:~/mySpace/other/ERT# ./a.out
This is a son thread
root@ubuntu:~/mySpace/other/ERT#
e.互斥鎖?
#include <iostream>
#include <thread>
#include <mutex>std::mutex mtx;
int shared_data = 0;void increment() {mtx.lock();std::thread::id current_id = std::this_thread::get_id();std::cout<<"current id = "<<current_id<<std::endl;++shared_data;mtx.unlock();
}// 更安全的方式:使用RAII鎖
void safe_increment() {// 離開作用域時自動解鎖std::lock_guard<std::mutex> lock(mtx);++shared_data;
}int main() {std::thread::id main_thread_id = std::this_thread::get_id(); // 當前線程std::thread t1(increment);std::thread t2(increment);t1.join();t2.join();std::cout<<"shared_date ="<<shared_data<<std::endl;return 0;
}輸出:
root@ubuntu:~/mySpace/other/ERT# ./a.out
current id = 140137569199872
current id = 140137560807168
shared_date =2
root@ubuntu:~/mySpace/other/ERT#
f.原子操作
#include <iostream>
#include <thread>
#include <mutex>
#include <atomic>std::atomic<int> counter(0);void increment() {for (int i = 0; i < 1000; ++i) {++counter; // 原子操作,無需額外同步}
}int main() {std::thread t1(increment);std::thread t2(increment);t1.join();t2.join();std::cout << counter<<std::endl; // 總是2000return 0;
}輸出:
root@ubuntu:~/mySpace/other/ERT# ./a.out
2000
root@ubuntu:~/mySpace/other/ERT#
g.異步操作
? ? ? ? 字段(Future/Promise/Async)?std::future
、std::promise
?和?std::async
?來簡化異步編程,它們共同構成了 C++ 的?并發編程模型,用于處理多線程任務和異步操作
std::async?簡化異步任務的啟動
#include <iostream>
#include <thread>
#include <mutex>
#include <atomic>
#include <future>int compute() {// 模擬耗時計算std::this_thread::sleep_for(std::chrono::seconds(1));return 42;
}void fun(){std::cout<<"This fun"<<std::endl;
}
int main() {std::future<int> result = std::async(std::launch::async, compute);// 可以做其他工作創建一個線程運行std::thread t(fun);t.join();std::cout << "Result: " << result.get() << "\n"; // 阻塞直到結果就緒return 0;
}輸出:
root@ubuntu:~/mySpace/other/ERT# ./a.out
This fun
Result: 42
root@ubuntu:~/mySpace/other/ERT#
?std::future: 用于獲取異步計算的結果(阻塞等待)-未來值
-
功能:表示一個?異步計算的結果(可能在另一個線程中計算)。
-
特點:
-
通過?
get()
?獲取結果(如果結果未就緒,會阻塞當前線程直到計算完成)。 -
只能獲取一次結果(第二次調用?
get()
?拋出異常)。 -
通過?
wait()
?等待結果就緒(不獲取值)。
-
-
適用場景:獲取異步任務(如?
std::async
?或?std::promise
)的返回值?
? ? ? ? 案例:
#include <iostream>
#include <thread>
#include <mutex>
#include <atomic>
#include <future>int compute() {std::this_thread::sleep_for(std::chrono::seconds(2));std::cout << "during: " << 2 << std::endl;return 42; // 模擬耗時計算
}int main() {std::future<int> fut = std::async(std::launch::async, compute);// 異步啟動一個任務std::cout << "Waiting for result..." << std::endl;int result = fut.get(); // 阻塞直到 compute() 完成std::cout << "Result: " << result << std::endl;return 0;
}輸出:
root@ubuntu:~/mySpace/other/ERT# ./a.out
Waiting for result...
during: 2
Result: 42
root@ubuntu:~/mySpace/other/ERT#
?std::promise:?用于線程間傳遞數據(生產者-消費者模式)
-
功能:用于?在線程間傳遞數據,允許一個線程設置值,另一個線程通過?
std::future
?獲取該值。 -
特點:
-
promise.set_value()
?設置值,并通知?future
?可以獲取。 -
如果?
promise
?被銷毀但未設置值,future.get()
?會拋出?std::future_error
。
-
-
適用場景:線程間通信,特別是當一個線程需要等待另一個線程的計算結果時。
案例:
????????
#include <iostream>
#include <thread>
#include <mutex>
#include <atomic>
#include <future>void compute(std::promise<int> prom) {prom.set_value(42); // 設置值
}int main() {// 創建promise對象std::promise<int> prom;// 通過future獲取值std::future<int> fut = prom.get_future(); // 通過移動給prom賦值std::thread t(compute, std::move(prom)); // 傳遞 promise// 阻塞直到 compute() 設置值int result = fut.get(); std::cout << "Result: " << result << std::endl;t.join();return 0;
}輸出:
root@ubuntu:~/mySpace/other/ERT# ./a.out
Result: 42
root@ubuntu:~/mySpace/other/ERT#
8. 線程局部存儲?
? ? ? ? a.局部全局變量
????????thread_local int tls_var = 0; ??每個線程都有自己的 tls_var
#include <iostream>
#include <thread>// 每個線程都有自己的 tls_var,跟linux系統中__thread關鍵類似,多線程中,每個線程都獨有一份全局變量。
thread_local int tls_var = 0; void increment() {tls_var++; // 修改的是當前線程的副本std::cout << "Thread " << std::this_thread::get_id() << ": tls_var = " << tls_var << std::endl;
}int main() {std::thread t1(increment); // t1 的 tls_var 初始為 0,執行后變為 1std::thread t2(increment); // t2 的 tls_var 初始為 0,執行后變為 1t1.join();t2.join();return 0;
}
? ? ? ? b.類的靜態線程局部變量
????????
#include <iostream>
#include <thread>class Counter {
public:// 每個線程有自己的 countstatic thread_local int count; void increment() {count++;std::cout << "Thread " << std::this_thread::get_id() << ": count = " << count << std::endl;}
};// 靜態成員類外初始化
thread_local int Counter::count = 0; int main() {Counter c;// t1 的 count 初始 0 → 1std::thread t1([&c]() {c.increment(); }); // t2 的 count 初始 0 → 1std::thread t2([&c]() { c.increment(); }); t1.join();t2.join();return 0;
}輸出:每個線程都獨享一份變量count
root@ubuntu:~/mySpace/other/ERT# ./a.out
Thread 140491193476864: count = 1
Thread 140491185084160: count = 1
root@ubuntu:~/mySpace/other/ERT#
以上就是c++11新特性總結筆記,可能還未完全,后續繼續完善!歡迎學習指點!共同進步!!!