c++11新特性,所有知識點都在這了!

2021-02-13 光城

c++程式設計師面試過程中基本上都會被問到c++11新特性吧,你是怎麼回答的呢?

本文基本上涵蓋了c++11的所有新特性,並有詳細代碼介紹其用法,對關鍵知識點做了深入分析,對重要的知識點我單獨寫了相關文章並附上了相關連結,我整理了完備的c++新特性腦圖(由於圖片太大,我沒有放在文章裡,同學可以在後臺回復消息「新特性」,即可下載完整圖片)。

auto & decltype

關於C++11新特性,最先提到的肯定是類型推導,C++11引入了auto和decltype關鍵字,使用他們可以在編譯期就推導出變量或者表達式的類型,方便開發者編碼也簡化了代碼。

cont int &i = 1;int a = 2;decltype(i) b = 2; 

關於auto和decltype的詳細介紹請看:一文吃透C++11中auto和decltype知識點

左值右值

眾所周知C++11新增了右值引用,這裡涉及到很多概念:

左值:可以取地址並且有名字的東西就是左值。

右值:不能取地址的沒有名字的東西就是右值。

純右值:運算表達式產生的臨時變量、不和對象關聯的原始字面量、非引用返回的臨時變量、lambda表達式等都是純右值。

將亡值:可以理解為即將要銷毀的值。

左值引用:對左值進行引用的類型。

右值引用:對右值進行引用的類型。

移動語義:轉移資源所有權,類似於轉讓或者資源竊取的意思,對於那塊資源,轉為自己所擁有,別人不再擁有也不會再使用。

完美轉發:可以寫一個接受任意實參的函數模板,並轉發到其它函數,目標函數會收到與轉發函數完全相同的實參。

返回值優化:當函數需要返回一個對象實例時候,就會創建一個臨時對象並通過複製構造函數將目標對象複製到臨時對象,這裡有複製構造函數和析構函數會被多餘的調用到,有代價,而通過返回值優化,C++標準允許省略調用這些複製構造函數。

這裡的詳細介紹請看:左值引用、右值引用、移動語義、完美轉發,你知道的不知道的都在這裡

列表初始化

在C++11中可以直接在變量名後面加上初始化列表來進行對象的初始化,詳細介紹一定要看這篇文章:學會C++11列表初始化

std::function & std::bind & lambda表達式

c++11新增了std::function、std::bind、lambda表達式等封裝使函數調用更加方便,詳細介紹請看:搞定c++11新特性std::function和lambda表達式

模板的改進

C++11關於模板有一些細節的改進:

詳細介紹請看:C++11的模板改進

並發

c++11關於並發引入了好多好東西,有:

詳細介紹請看:c++11新特性之線程相關所有知識點

這裡也使用c++11來實現的線程池和定時器,可以看:

C++線程池的實現之格式修訂版

C++定時器的實現之格式修訂版

智能指針

很多人談到c++,說它特別難,可能有一部分就是因為c++的內存管理吧,不像java那樣有虛擬機動態的管理內存,在程序運行過程中可能就會出現內存洩漏,然而這種問題其實都可以通過c++11引入的智能指針來解決,相反我還認為這種內存管理還是c++語言的優勢,因為盡在掌握。

c++11引入了三種智能指針:

std::shared_ptr

std::weak_ptr

std::unique_ptr

詳細介紹請看:c++11新特性之智能指針

基於範圍的for循環

直接看代碼

vector<int> vec;
for (auto iter = vec.begin(); iter != vec.end(); iter++) { cout << *iter << endl;}
for (int i : vec) { cout << "i" << endl;}

委託構造函數

委託構造函數允許在同一個類中一個構造函數調用另外一個構造函數,可以在變量初始化時簡化操作,通過代碼來感受下委託構造函數的妙處吧:

不使用委託構造函數:

struct A {   A(){}   A(int a) { a_ = a; }
A(int a, int b) { a_ = a; b_ = b; }
A(int a, int b, int c) { a_ = a; b_ = b; c_ = c; }
int a_; int b_; int c_;};

使用委託構造函數:

struct A {   A(){}   A(int a) { a_ = a; }
A(int a, int b) : A(a) { b_ = b; }
A(int a, int b, int c) : A(a, b) { c_ = c; }
int a_; int b_; int c_;};

初始化變量是不是方便了許多。

繼承構造函數

繼承構造函數可以讓派生類直接使用基類的構造函數,如果有一個派生類,我們希望派生類採用和基類一樣的構造方式,可以直接使用基類的構造函數,而不是再重新寫一遍構造函數,老規矩,看代碼:

不使用繼承構造函數:

struct Base {   Base() {}   Base(int a) { a_ = a; }
Base(int a, int b) : Base(a) { b_ = b; }
Base(int a, int b, int c) : Base(a, b) { c_ = c; }
int a_; int b_; int c_;};
struct Derived : Base { Derived() {} Derived(int a) : Base(a) {} Derived(int a, int b) : Base(a, b) {} Derived(int a, int b, int c) : Base(a, b, c) {} };int main() { Derived a(1, 2, 3); return 0;}

使用繼承構造函數:

struct Base {   Base() {}   Base(int a) { a_ = a; }
Base(int a, int b) : Base(a) { b_ = b; }
Base(int a, int b, int c) : Base(a, b) { c_ = c; }
int a_; int b_; int c_;};
struct Derived : Base { using Base::Base;};
int main() { Derived a(1, 2, 3); return 0;}

只需要使用using Base::Base繼承構造函數,就免去了很多重寫代碼的麻煩。

nullptr

nullptr是c++11用來表示空指針新引入的常量值,在c++中如果表示空指針語義時建議使用nullptr而不要使用NULL,因為NULL本質上是個int型的0,其實不是個指針。舉例:

void func(void *ptr) {   cout << "func ptr" << endl;}
void func(int i) { cout << "func i" << endl;}
int main() { func(NULL); func(nullptr); return 0;}

final & override

c++11關於繼承新增了兩個關鍵字,final用於修飾一個類,表示禁止該類進一步派生和虛函數的進一步重載,override用於修飾派生類中的成員函數,標明該函數重寫了基類函數,如果一個函數聲明了override但父類卻沒有這個虛函數,編譯報錯,使用override關鍵字可以避免開發者在重寫基類函數時無意產生的錯誤。

示例代碼1:

struct Base {   virtual void func() {       cout << "base" << endl;  }};
struct Derived : public Base{ void func() override { cout << "derived" << endl; }
void fu() override { }};

示例代碼2:

struct Base final {   virtual void func() {       cout << "base" << endl;  }};
struct Derived : public Base{ void func() override { cout << "derived" << endl; }
};

default

c++11引入default特性,多數時候用於聲明構造函數為默認構造函數,如果類中有了自定義的構造函數,編譯器就不會隱式生成默認構造函數,如下代碼:

struct A {   int a;   A(int i) { a = i; }};
int main() { A a; return 0;}

上面代碼編譯出錯,因為沒有匹配的構造函數,因為編譯器沒有生成默認構造函數,而通過default,程式設計師只需在函數聲明後加上「=default;」,就可將該函數聲明為 defaulted 函數,編譯器將為顯式聲明的 defaulted 函數自動生成函數體,如下:

struct A {   A() = default;   int a;   A(int i) { a = i; }};
int main() { A a; return 0;}

編譯通過。

delete

c++中,如果開發人員沒有定義特殊成員函數,那麼編譯器在需要特殊成員函數時候會隱式自動生成一個默認的特殊成員函數,例如拷貝構造函數或者拷貝賦值操作符,如下代碼:

struct A {   A() = default;   int a;   A(int i) { a = i; }};
int main() { A a1; A a2 = a1; A a3; a3 = a1; }

而我們有時候想禁止對象的拷貝與賦值,可以使用delete修飾,如下:

struct A {   A() = default;   A(const A&) = delete;   A& operator=(const A&) = delete;   int a;   A(int i) { a = i; }};
int main() { A a1; A a2 = a1; A a3; a3 = a1; }

delele函數在c++11中很常用,std::unique_ptr就是通過delete修飾來禁止對象的拷貝的。

explicit

explicit專用於修飾構造函數,表示只能顯式構造,不可以被隱式轉換,根據代碼看explicit的作用:

不用explicit:

struct A {   A(int value) {        cout << "value" << endl;  }};
int main() { A a = 1; return 0;}

使用explicit:

struct A {   explicit A(int value) {       cout << "value" << endl;  }};
int main() { A a = 1; A aa(2); return 0;}

const

因為要講後面的constexpr,所以這裡簡單介紹下const。

const字面意思為只讀,可用於定義變量,表示變量是只讀的,不可以更改,如果更改,編譯期間就會報錯。

主要用法如下:

用於定義常量,const的修飾的變量不可更改。

指針也可以使用const,這裡有個小技巧,從右向左讀,即可知道const究竟修飾的是指針還是指針所指向的內容。

char *const ptr; const char* ptr; 

在函數參數中使用const,一般會傳遞類對象時會傳遞一個const的引用或者指針,這樣可以避免對象的拷貝,也可以防止對象被修改。

class A{};void func(const A& a);

const修飾類的成員變量,表示是成員常量,不能被修改,可以在初始化列表中被賦值。

class A {const int value = 5;};class B {const int value;B(int v) : value(v){}};

修飾類成員函數,表示在該函數內不可以修改該類的成員變量。

class A{void func() const;};

修飾類對象,類對象只能調用該對象的const成員函數。

class A {void func() const;};const A a;a.func();

constexpr

constexpr是c++11新引入的關鍵字,用於編譯時的常量和常量函數,這裡直接介紹constexpr和const的區別:

兩者都代表可讀,const只表示read only的語義,只保證了運行時不可以被修改,但它修飾的仍然有可能是個動態變量,而constexpr修飾的才是真正的常量,它會在編譯期間就會被計算出來,整個運行過程中都不可以被改變,constexpr可以用於修飾函數,這個函數的返回值會儘可能在編譯期間被計算出來當作一個常量,但是如果編譯期間此函數不能被計算出來,那它就會當作一個普通函數被處理。如下代碼:

#include<iostream>using namespace std;
constexpr int func(int i) { return i + 1;}
int main() { int i = 2; func(i); func(2);}

enum class

c++11新增有作用域的枚舉類型,看代碼

不帶作用域的枚舉代碼:

enum AColor {   kRed,   kGreen,   kBlue};
enum BColor { kWhite, kBlack, kYellow};
int main() { if (kRed == kWhite) { cout << "red == white" << endl; } return 0;}

如上代碼,不帶作用域的枚舉類型可以自動轉換成整形,且不同的枚舉可以相互比較,代碼中的紅色居然可以和白色比較,這都是潛在的難以調試的bug,而這種完全可以通過有作用域的枚舉來規避。

有作用域的枚舉代碼:

enum class AColor {   kRed,   kGreen,   kBlue};
enum class BColor { kWhite, kBlack, kYellow};
int main() { if (AColor::kRed == BColor::kWhite) { cout << "red == white" << endl; } return 0;}

使用帶有作用域的枚舉類型後,對不同的枚舉進行比較會導致編譯失敗,消除潛在bug,同時帶作用域的枚舉類型可以選擇底層類型,默認是int,可以改成char等別的類型。

enum class AColor : char {   kRed,   kGreen,   kBlue};

我們平時編程過程中使用枚舉,一定要使用有作用域的枚舉取代傳統的枚舉。

非受限聯合體

c++11之前union中數據成員的類型不允許有非POD類型,而這個限制在c++11被取消,允許數據成員類型有非POD類型,看代碼:

struct A {   int a;   int *b;};
union U { A a; int b;};

對於什麼是POD類型,大家可以自行查下資料,大體上可以理解為對象可以直接memcpy的類型。

sizeof

c++11中sizeof可以用的類的數據成員上,看代碼:

c++11前:

struct A {   int data[10];   int a;};
int main() { A a; cout << "size " << sizeof(a.data) << endl; return 0;}

c++11後:

struct A {   int data[10];   int a;};
int main() { cout << "size " << sizeof(A::data) << endl; return 0;}

想知道類中數據成員的大小在c++11中是不是方便了許多,而不需要定義一個對象,在計算對象的成員大小。

assertion
static_assert(true/false, message);

c++11引入static_assert聲明,用於在編譯期間檢查,如果第一個參數值為false,則列印message,編譯失敗。

自定義字面量

c++11可以自定義字面量,我們平時c++中都或多或少使用過chrono中的時間,例如:

std::this_thread::sleep_for(std::chrono::milliseconds(100)); std::this_thread::sleep_for(std::chrono::seconds(100)); 

其實沒必要這麼麻煩,也可以這麼寫:

std::this_thread::sleep_for(100ms); std::this_thread::sleep_for(100s);

這就是自定義字面量的使用,示例如下:

struct mytype {   unsigned long long value;};constexpr mytype operator"" _mytype ( unsigned long long n ) {   return mytype{n};}mytype mm = 123_mytype;cout << mm.value << endl;

關於自定義字面量,可以看下chrono的原始碼,相信大家會有很大收穫,需要源碼分析chrono的話,可以留言給我。

內存對齊什麼是內存對齊

理論上計算機對於任何變量的訪問都可以從任意位置開始,然而實際上系統會對這些變量的存放地址有限制,通常將變量首地址設為某個數N的倍數,這就是內存對齊。

為什麼要內存對齊

硬體平臺限制,內存以字節為單位,不同硬體平臺不一定支持任何內存地址的存取,一般可能以雙字節、4位元組等為單位存取內存,為了保證處理器正確存取數據,需要進行內存對齊。

提高CPU內存訪問速度,一般處理器的內存存取粒度都是N的整數倍,假如訪問N大小的數據,沒有進行內存對齊,有可能就需要兩次訪問才可以讀取出數據,而進行內存對齊可以一次性把數據全部讀取出來,提高效率。

在c++11之前如果想創建內存對齊需要:

void align_cpp11_before(){   static char data[sizeof(void *) + sizeof(A)];   const uintptr_t kAlign = sizeof(void *) - 1;   char *align_ptr =       reinterpret_cast<char *>(reinterpret_cast<uintptr_t>(data + kAlign) & ~kAlign);   A *attr = new (align_ptr) A;}

c++11關於內存對齊新增了一些函數:

void align_cpp11_after(){   static std::aligned_storage<sizeof(A),                               alignof(A)>::type data;   A *attr = new (&data) A;}

還有:alignof()、std::alignment_of()、alignas(),關於內存對齊詳情可以看這篇文章:內存對齊之格式修訂版

thread_local

c++11引入thread_local,用thread_local修飾的變量具有thread周期,每一個線程都擁有並只擁有一個該變量的獨立實例,一般用於需要保證線程安全的函數中。

#include <iostream>#include <thread>
class A { public: A() {} ~A() {}
void test(const std::string &name) { thread_local int count = 0; ++count; std::cout << name << ": " << count << std::endl; }};
void func(const std::string &name) { A a1; a1.test(name); a1.test(name); A a2; a2.test(name); a2.test(name);}
int main() { std::thread(func, "thread1").join(); std::thread(func, "thread2").join(); return 0;}

輸出:

thread1: 1thread1: 2thread1: 3thread1: 4thread2: 1thread2: 2thread2: 3thread2: 4

驗證上述說法,對於一個線程私有變量,一個線程擁有且只擁有一個該實例,類似於static。

基礎數值類型

c++11新增了幾種數據類型:long long、char16_t、char32_t等

隨機數功能

c++11關於隨機數功能則較之前豐富了很多,典型的可以選擇概率分布類型,先看如下代碼:

#include <time.h>
#include <iostream>#include <random>
using namespace std;
int main() { std::default_random_engine random(time(nullptr));
std::uniform_int_distribution<int> int_dis(0, 100); std::uniform_real_distribution<float> real_dis(0.0, 1.0);
for (int i = 0; i < 10; ++i) { cout << int_dis(random) << ' '; } cout << endl;
for (int i = 0; i < 10; ++i) { cout << real_dis(random) << ' '; } cout << endl;
return 0;}

輸出:

38 100 93 7 66 0 68 99 41 70.232202 0.617716 0.959241 0.970859 0.230406 0.430682 0.477359 0.971858 0.0171148 0.64863

代碼中舉例的是整數均勻分布和浮點數均勻分布,c++11提供的概率分布類型還有好多,例如伯努利分布、正態分布等,具體可以見最後的參考資料。

正則表達式

c++11引入了regex庫更好的支持正則表達式,見代碼:

#include <iostream>#include <iterator>#include <regex>#include <string>
int main() { std::string s = "I know, I'll use2 regular expressions."; std::regex self_regex("REGULAR EXPRESSIONS", std::regex_constants::icase); if (std::regex_search(s, self_regex)) { std::cout << "Text contains the phrase 'regular expressions'\n"; }
std::regex word_regex("(\\w+)"); auto words_begin = std::sregex_iterator(s.begin(), s.end(), word_regex); auto words_end = std::sregex_iterator();
std::cout << "Found " << std::distance(words_begin, words_end) << " words\n";
const int N = 6; std::cout << "Words longer than " << N << " characters:\n"; for (std::sregex_iterator i = words_begin; i != words_end; ++i) { std::smatch match = *i; std::string match_str = match.str(); if (match_str.size() > N) { std::cout << " " << match_str << '\n'; } }
std::regex long_word_regex("(\\w{7,})"); std::string new_s = std::regex_replace(s, long_word_regex, "[$&]"); std::cout << new_s << '\n';}

chrono

c++11關於時間引入了chrono庫,源於boost,功能強大,chrono主要有三個點:

duration

std::chrono::duration表示一段時間,常見的單位有s、ms等,示例代碼:

std::this_thread::sleep_for(std::chrono::milliseconds(100));

sleep_for裡面其實就是std::chrono::duration,表示一段時間,實際是這樣:

typedef duration<int64_t, milli> milliseconds;typedef duration<int64_t> seconds;

duration具體模板如下:

1 template <class Rep, class Period = ratio<1> > class duration;

Rep表示一種數值類型,用來表示Period的數量,比如int、float、double,Period是ratio類型,用來表示【用秒表示的時間單位】比如second,常用的duration<Rep, Period>已經定義好了,在std::chrono::duration下:

ratio<3600, 1>:hours

ratio<60, 1>:minutes

ratio<1, 1>:seconds

ratio<1, 1000>:microseconds

ratio<1, 1000000>:microseconds

ratio<1, 1000000000>:nanosecons

ratio的具體模板如下:

template <intmax_t N, intmax_t D = 1> class ratio;

N代表分子,D代表分母,所以ratio表示一個分數,我們可以自定義Period,比如ratio<2, 1>表示單位時間是2秒。

time_point

表示一個具體時間點,如2020年5月10日10點10分10秒,拿獲取當前時間舉例:

std::chrono::time_point<std::chrono::high_resolution_clock> Now() {   return std::chrono::high_resolution_clock::now();}

clocks

時鐘,chrono裡面提供了三種時鐘:

steady_clock

system_clock

high_resolution_clock

steady_clock

穩定的時間間隔,表示相對時間,相對於系統開機啟動的時間,無論系統時間如何被更改,後一次調用now()肯定比前一次調用now()的數值大,可用於計時。

system_clock

表示當前的系統時鐘,可以用於獲取當前時間:

int main() {   using std::chrono::system_clock;   system_clock::time_point today = system_clock::now();
std::time_t tt = system_clock::to_time_t(today); std::cout << "today is: " << ctime(&tt);
return 0;}

high_resolution_clock

high_resolution_clock表示系統可用的最高精度的時鐘,實際上就是system_clock或者steady_clock其中一種的定義,官方沒有說明具體是哪個,不同系統可能不一樣,我之前看gcc chrono源碼中high_resolution_clock是steady_clock的typedef。

更多關於chrono的介紹可以看下我之前的文章:RAII妙用之計算函數耗時

新增數據結構
std::forward_list<int> fl = {1, 2, 3, 4, 5};for (const auto &elem : fl) {   cout << elem;}

std::unordered_set:基於hash表實現的set,內部不會排序,使用方法和set類似

std::unordered_map:基於hash表實現的map,內部不會排序,使用方法和set類似

std::array:數組,在越界訪問時拋出異常,建議使用std::array替代普通的數組

std::tuple:元組類型,類似pair,但比pair擴展性好

typedef std::tuple<int, double, int, double> Mytuple;Mytuple t(0, 1, 2, 3);std::cout << "0 " << std::get<0>(t);std::cout << "1 " << std::get<1>(t);std::cout << "2 " << std::get<2>(t);std::cout << "3 " << std::get<3>(t);

新增算法

std::vector<int> v(10, 2);if (std::all_of(v.cbegin(), v.cend(), [](int i) { return i % 2 == 0; })) {std::cout << "All numbers are even\n";}

any_of:檢測表達式是否對範圍[first, last)中至少一個元素返回true,如果滿足,則返回true,否則返回false,用法和上面一樣

none_of:檢測表達式是否對範圍[first, last)中所有元素都不返回true,如果都不滿足,則返回true,否則返回false,用法和上面一樣

find_if_not:找到第一個不符合要求的元素迭代器,和find_if相反

copy_if:複製滿足條件的元素

itoa:對容器內的元素按序遞增

std::vector<int> l(10);std::iota(l.begin(), l.end(), 19); for (auto n : l) std::cout << n << ' ';

int main() {   std::vector<int> v = {3, 9, 1, 4, 2, 5, 9};
auto result = std::minmax_element(v.begin(), v.end()); std::cout << "min element at: " << *(result.first) << '\n'; std::cout << "max element at: " << *(result.second) << '\n'; return 0;}

關於c++11的新特性基本上就是這些,相信各位看完一定會有所收穫。

參考資料https://zh.cppreference.com/w/cpp/language/range-forhttps://juejin.im/post/5dcaa857e51d457f7675360bhttps://zhuanlan.zhihu.com/p/21930436https://zh.wikipedia.org/wiki/Nullptrhttps://zh.wikipedia.org/wiki/Constexprhttps://zh.cppreference.com/w/cpp/language/enumhttps://kheresy.wordpress.com/2019/03/27/using-enum-class/https://zh.cppreference.com/w/cpp/language/unionhttp://c.biancheng.net/view/7165.htmlhttps://zhuanlan.zhihu.com/p/77585472http://www.cplusplus.com/reference/random/https://zh.cppreference.com/w/cpp/regexhttps://www.cnblogs.com/jwk000/p/3560086.htmlhttps://zh.cppreference.com/w/cpp/algorithm/all_any_none_of作者公眾號:

持續關注~

相關焦點

  • C++14新特性的所有知識點全在這兒啦!
    前面程序喵介紹過C++11的新特性,這篇文章介紹下C++14的新特性。
  • C++17新特性介紹:std::optional
    在這種情況下,我們可以嘗試一下C++17裡的新特性:std::optional。過時的解決辦法在前面描述的問題中,如果不採用std::optional,我們還是有辦法解決的。對於上面傳感器讀數的特定問題,我們的函數可以返回一個float的最大值FLT_MAX,當然,這就要求調用這個函數的程序特別處理這個特殊的返回值了。
  • C++11新特性(80)-繼承的構造函數與多重繼承
    對於繼承的構造函數,C++11通過一個簡單的using語句,使得繼承一個類時可以省去一些麻煩。具體可以參照下面的文章。C++11新特性(59)-繼承的構造函數https://mp.weixin.qq.com/s/BGUa7-RSCtFRnBYjUVFFDA
  • 【C++面試知識】C++11新特性
    來源:https://blog.csdn.net/a15920804211/article/details/906915251.新的
  • 新手入門:關於C++中的內聯函數(inline)
    >   在c++中,為了解決一些頻繁調用的小函數大量消耗棧空間或者是叫棧內存的問題,特別的引入了inline修飾符,表示為內聯函數。奇":"偶";    }  上面的例子就是標準的內聯函數的用法,使用inline修飾帶來的好處我們表面看不出來,其實在內部的工作就是在每個for循環的內部所有調用dbtest(i)的地方都換成了(i%2>0)?"奇":"偶"這樣就避免了頻繁調用函數對棧內存重複開闢所帶來的消耗。
  • c++11-17 模板核心知識(零)—— 導語
    Guide為什麼要整理 cpp11-17TemplateTutorial緣起於看 folly 源碼時有好多模板相關的語法,遇到不會的需要經常查,給閱讀帶來極大的困難。其中,內容零散不系統對於我來說是一個最大的問題,因為我 C++模板沒有寫過多少,對於某一個特性或者用法,不知道其在模板的知識體系框架中處在什麼位置、解決了什麼問題,想要查相關的語法都不知道怎麼查、查的關鍵詞是什麼。 所以,我根據後面列出的三個參考資料,整理了模板的核心知識點,內容不求涉及到所有方面,但求梳理出主要脈絡,同時融入 C++11-17 模板的新特性。
  • C 語言會比 C++ 快?
    截至目前,儘管其中仍包含一些 C ++ 特性,但整體上來看,其代碼已與 C 極為相似。這些變化背後有很多原因,例如刪除 C++ 11 的要求可以確保任何人都能在任何平臺上編譯庫;刪除 std::vector 大大改進了未優化構建的性能;刪除 algorithm 可以提升編譯速度等等。但是,我目前更改的這個代碼庫並沒有完全變成 C 語言的代碼。
  • C++ 的門門道道 | 技術頭條 - CSDN
    相信工作5年以上至少50%的C/C++程式設計師都被它坑過,我已經聽到過了無數個悲傷的故事,《聖鬥士星矢》,《仙劍》,還有別人家的項目《天天愛消除》,都有人掉坑,程序運行幾天莫名奇妙的Crash掉,這鍋好沉。
  • C++11新特性(13)-使用大括號包圍的值列表賦值
    C++11新特性(2)- 列表初始化除了初始化之外,這種形式也可以用於賦值語句中。
  • 「最佳實踐」C++陷阱與套路
    ,而當你正跟別人談笑風生的時候,忽然crash,這就尷尬了。運行過程中需要動態增刪的vector,不宜存放大的對象本身 ,因為擴容會導致所有成員拷貝構造,消耗較大,可以通過保存對象指針替代。理解at()和operator[]的區別 :at()會做下標越界檢查,operator[]提供數組索引級的訪問,在release版本下不會檢查下標,VC會在Debug版本會檢查;c++標準規定:operator[]不提供下標安全性檢查。5. C++標準規定了std::vector的底層用數組實現,認清這一點並利用這一點。
  • C++ 過去的這一年
    Visual Studio團隊宣布Visual Studio 2017 15.7版完全支持C++ 17,這也意味著它對C++ 11/14的支持。現在,你可以構建複雜的代碼庫,如boost::hana或range v3。既然C++ 11/14在所有主流編譯器中都得到了支持,那麼就不存在任何理由不使用現代C++了。
  • 中考物理知識點:特性
    中考物理知識點:特性   一音調:   ⑴定義:聲音的高低叫音調。   ⑵決定音調高低的因素:   ①實驗:把鋼尺伸出桌面不同的長度,用相同大小的力撥動,聽聲音。   伸出的越短,音調越高。 相關推薦:中考物理知識點:聲音的產生和傳播方式 點擊查看更多信息 新初三快掃碼關注   中考網微信公眾號
  • C++機器學習庫介紹
    這是個公平的問題。像Python和R這樣的語言有大量的包和庫來滿足不同的機器學習任務。那麼C++有沒有這樣的產品呢?是的,是的!在本文中,我將重點介紹兩個這樣的C++庫,我們也將看到它們都可以運行。目錄為什麼我們要使用機器學習庫?
  • VISUAL C++全能速查寶典 高清pdf
    本書分為兩部分,共17章,前7章是c函數部分,每一章是一個分類,共囊括了143個函數;後10章是mfc類,同樣是按章分類,共包含77個類、1102個方法,內容涉及visual c++中的各種技術。每一個知識點都配有具體的示例,便於讀者理解。需要的朋友關注後私信我,大量優質電子資料分享!
  • C++基礎總結(一):從「hello world」入門C++!
    最近對C++的基礎知識進行了大匯總,當然這是精簡版的,但是篇幅也不少,所以今天先分享一下hello world,建議大家收藏慢慢學習,同時希望對大家的C++學習有所幫助。C++ 是一種靜態類型的、編譯式的、通用的、大小寫敏感的、不規則的程式語言,支持過程化編程、面向對象編程和泛型編程。C++ 被認為是一種中級語言,它綜合了高級語言和低級語言的特點。
  • C++11特性:decltype關鍵字
    同時在C++11中typeid還提供了hash_code這個成員函數,用於返回類型的唯一哈希值。RTTI會導致運行時效率降低,且在泛型編程中,我們更需要的是編譯時就要確定類型,RTTI並無法滿足這樣的要求。編譯時類型推導的出現正是為了泛型編程,在非泛型編程中,我們的類型都是確定的,根本不需要再進行推導。而編譯時類型推導,除了我們說過的auto關鍵字,還有本文的decltype。
  • PHP7.0 的新特性
    PHP7.0 的新特性經常會被面試官問到,在平時的項目開發中運用它們也會提升一定的代碼質量和代碼運行性能,可見這個知識點的重要性。不過有很多人都沒有去系統的了解掌握,今天我剛好系統整理了一番分享出來。/** * 所有訂單詳情都是通過這個入口 * @param $orderNo * @return array|mixed
  • python+C、C++混合編程的應用
    我看到的一個很好的Python與c/c++混合編程的應用是NS3(Network Simulator3)一款網絡模擬軟體,它的內部計算引擎需要用高性能,但在用戶建模部分需要靈活易用。NS3的選擇是使用C/C++來模擬核心部件和協議,用python來建模和擴展。這篇文章介紹python和c/c++三種混合編程的方法,並對性能加以分析。
  • 中考物理知識點:聲音的特性考點
    中考物理知識點:聲音的特性考點   關於聲現象,下列說法錯誤的是()   A.人耳聽不到蝴蝶翅膀振動的聲音,是因為蝴蝶翅膀振動的幅度太小   B.詩句「不敢高聲語,恐驚天上人」的「高」指聲音的響度大   C.用聲波能粉碎人體內的「小石頭」,說明聲波具有能量
  • C++後端開發面試題與知識點匯總(附答案)
    以下匯總C++後臺開發面試題與知識點,還有其他崗位的相關題庫和資料,想要什麼崗位的可以留言哦~附面試題目:一、基礎知識1、基本語言說一下C++和C的區別說一下C++中static關鍵字的作用說一說c++中四種cast轉換請說一下C/C++ 中指針和引用的區別?