2020-06-03----------------------------------------------------------------------------------------------------------------------------------------------------------
左值引用vs右值引用https://blog.csdn.net/xuyuqingfeng953/article/details/51058236
左值引用和直接傳遞了實參有區別麼?
tuple, forward_as_tuplehttps://www.cnblogs.com/LuckCoder/p/8632209.html
2020-04-03------------------------------------------------------------------------------------------------------------------------------------------------------------------
指針作爲類的成員變量,我想要改變指針的內容,指針的指針和指針的引用還是有區別的,
2020-3-23-----------------------------------------------------------------------------------------------------------------------------------------------------------如果new了一片內存賦值給指針p,通過delete的方式回收了內存,這時內存回收了,但是指針p依然指向這片未分配的內存區域,成爲野指針,結果是不確定的,因而在delete釋放內存的同時,需要手動通過p=nullptr將p置空 。同樣,定義的時候也需要初始化。
2020-3-20-----------------------------------------------------------------------------------------------------------------------------------------------------------
class A{
A(input){
temp = input;
}
private:
int temp;
}
A a(5);
std::shared_ptr<A> p(new A);
std::shared_ptr<A> p = std::make_shared<A>(a);
std::shared_ptr<A> p = std::make_shared<A>(5);
make_shared後面跟A類的一個對象或者構造函數裏的參數,都是可以的。
2020-3-17-----------------------------------------------------------------------------------------------------------------------------------------------------------vector可以assign(n, digit);可以resize(大小),改變size,過大capacity會自動擴容; 也可以 reserve主動擴容,改變capacity.
resize更大之後,好像默認賦值0;resize更小之後,size變小了,但是原來的位置可以訪問,而且還是原來的值,物理內存上的內容並沒有改變.
thread及時回收,防止資源泄露https://www.cnblogs.com/liangjf/p/9801496.html
多線程cmake設置:
find_package (Threads)
add_executable (myapp main.cpp ...)
target_link_libraries (myapp ${CMAKE_THREAD_LIBS_INIT})
互斥鎖std::mutex和條件變量std::condition_variable
——> > > std::mutex: std::mutex是C++中最基本的互斥量,提供了獨佔所有權的特性,std::mutex提供了以下成員函數:
構造函數:std::mutex不允許拷貝構造,也不允許move拷貝,最初產生的mutex對象是處於unlocked狀態的。
lock():調用線程將鎖住該互斥量,線程調用該函數會發生以下3種情況:
(1)如果該互斥量當前沒有被鎖住,則調用線程將該互斥量鎖住,直到調用unlock之前,該線程一直擁有該鎖。
(2)如果當前互斥量被其他線程鎖住,則當前的調用線程被阻塞住。
(3)如果當前互斥量被當前調用線程鎖住,則會產生死鎖,,也就是說同一個線程中不允許鎖兩次。
unlock():解鎖,釋放對互斥量的所有權。
try_lock():嘗試鎖住互斥量,如果互斥量被其他線程佔有,則當前線程也不會被阻塞,線程調用該函數會出現下面3種情況:
(1)如果當前互斥量沒有被其他線程佔有,則該線程鎖住互斥量,直到該線程調用unlock釋放互斥量。
(2)如果當前互斥量被其他線程鎖住,則當前調用線程返回false,而並不會被阻塞掉。
(3)如果當前互斥量被當前調用線程鎖住,則會產生死鎖。
條件變量std::condition_variable:
條件變量是併發程序設計中的一種控制結構。多個線程訪問一個共享資源(或稱臨界區)時,不但需要用互斥鎖實現獨享訪問以避免併發錯誤(稱爲競爭危害),在獲得互斥鎖進入臨界區後還需要檢驗特定條件是否成立:C++11中引入了條件變量,其相關內容均在<condition_variable>中。這裏主要介紹std::condition_variable類。
(1)、如果不滿足該條件,擁有互斥鎖的線程應該釋放該互斥鎖,把自身阻塞(block)並掛到(suspend)條件變量的線程隊列中
(2)、如果滿足該條件,擁有互斥鎖的線程在臨界區內訪問共享資源,在退出臨界區時通知(notify)在條件變量的線程隊列中處於阻塞狀態的線程,被通知的線程必須重新申請對該互斥鎖加鎖。
條件變量std::condition_variable用於多線程之間的通信,它可以阻塞一個或同時阻塞多個線程。std::condition_variable需要與std::unique_lock配合使用。std::condition_variable效果上相當於包裝了pthread庫中的pthread_cond_*()系列的函數。
當std::condition_variable對象的某個wait函數被調用的時候,它使用std::unique_lock(通過std::mutex)來鎖住當前線程。當前線程會一直被阻塞,直到另外一個線程在相同的std::condition_variable對象上調用了notification函數來喚醒當前線程。
std::condition_variable對象通常使用std::unique_lock<std::mutex>來等待,如果需要使用另外的lockable類型,可以使用std::condition_variable_any類。
std::condition_variable類的成員函數:
(1)、構造函數:僅支持默認構造函數,拷貝、賦值和移動(move)均是被禁用的。
(2)、wait:當前線程調用wait()後將被阻塞,直到另外某個線程調用notify_*喚醒當前線程;當線程被阻塞時,該函數會自動調用std::mutex的unlock()釋放鎖,使得其它被阻塞在鎖競爭上的線程得以繼續執行。一旦當前線程獲得通知(notify,通常是另外某個線程調用notify_*喚醒了當前線程),wait()函數也是自動調用std::mutex的lock()。
wait分爲無條件被阻塞和帶條件的被阻塞兩種。
——> > > 無條件被阻塞:調用該函數前,當前線程應該已經對unique_lock<mutex> lck完成了加鎖。所有使用同一個條件變量的線程必須在wait函數中使用同一個unique_lock<mutex>。該wait函數內部會自動調用lck.unlock()對互斥鎖解鎖,使得其他被阻塞在互斥鎖上的線程恢復執行。使用本函數被阻塞的當前線程在獲得通知(notified,通過別的線程調用 notify_*系列的函數)而被喚醒後,wait()函數恢復執行並自動調用lck.lock()對互斥鎖加鎖。
——> > > 帶條件的被阻塞:wait函數設置了謂詞(Predicate),只有當pred條件爲false時調用該wait函數纔會阻塞當前線程,並且在收到其它線程的通知後只有當pred爲true時纔會被解除阻塞。因此,等效於while (!pred()) wait(lck).
(3)、wait_for:與wait()類似,只是wait_for可以指定一個時間段,在當前線程收到通知或者指定的時間超時之前,該線程都會處於阻塞狀態。而一旦超時或者收到了其它線程的通知,wait_for返回,剩下的步驟和wait類似。
(4)、wait_until:與wait_for類似,只是wait_until可以指定一個時間點,在當前線程收到通知或者指定的時間點超時之前,該線程都會處於阻塞狀態。而一旦超時或者收到了其它線程的通知,wait_until返回,剩下的處理步驟和wait類似。
(5)、notify_all: 喚醒所有的wait線程,如果當前沒有等待線程,則該函數什麼也不做。
(6)、notify_one:喚醒某個wait線程,如果當前沒有等待線程,則該函數什麼也不做;如果同時存在多個等待線程,則喚醒某個線程是不確定的(unspecified)。
條件變化存在虛假喚醒的情況,因此在線程被喚醒後需要檢查條件是否滿足。無論是notify_one或notify_all都是類似於發出脈衝信號,如果對wait的調用發生在notify之後是不會被喚醒的,所以接收者在使用wait等待之前也需要檢查條件是否滿足。
std::condition_variable_any類與std::condition_variable用法一樣,區別僅在於std::condition_variable_any的wait函數可以接受任何lockable參數,而std::condition_variable只能接受std::unique_lock<std::mutex>類型的參數。
std::notify_all_at_thread_exit函數:當調用該函數的線程退出時,所有在cond條件變量上等待的線程都會收到通知。
參考:
https://www.cnblogs.com/depend-wind/articles/10108048.html
https://www.cnblogs.com/zhanghu52030/p/9166737.html
2020-3-11------------------------------------------------------------------------------------------------------------------------------------------------------------
基類A,包含a, b兩個方法,其中a調用了b,且b是virtual;
派生類B,重寫了b,還新寫了個c函數;
基類指針p指向B的對象,不能調用c,因爲他也不知道派生類會有這麼個函數;
p調用函數a的時候,a又調用了函數b,因爲是virtual的且B中也重寫了,因此會調用B中的b。
2020-3-6---------------------------------------------------------------------------------------------------------------------------------------------------------------------
std::atan(y/x)
std::atan2(y, x)
atan的情況下,要保證x不會等於0;atan2允許x等於0,不需要特別考慮。做除法就要考慮分佈會不會存在等於0的風險。
不要用abs(), fabs()這種c的庫,統一用std::abs()
2020-3-5--------------------------------------------------------------------------------------------------------------------------------------------------------------------
enum 與enum class:
1.3 問題3:enum的作用域
enum的中的 ” { } ” 大括號並沒有將枚舉成員的可見域限制在大括號內,導致enum成員曝露到了上一級作用域(塊語句)中。
例如:
#include <iostream>
enum color{red,blue};//定義擁有兩個成員的enum,red和blue在enum的大括號外部可以直接訪問,而不需要使用域運算符。
int main() {
std::cout << blue << std::endl;
std::cin.get();
return 0;
}
就如上面的代碼,我們可以在blue的大括號之外訪問它,color的成員被泄露到了該文件的全局作用域中(雖然它尚不具備外部鏈接性)。可以直接訪問,而不需要域運算符的幫助。
但是這不是關鍵,有時我們反而覺得非常方便。下面纔是問題所在:
問題:無法定義同名的枚舉成員
enum color { red, blue };
//enum MyEnum { red, yellow }; ERROR, 重定義;以前的定義是“枚舉數”
如上面的代碼所示:我們無法重複使用red這個標識符。因爲它在color中已經被用過了。但是,它們明明就是不同的枚舉類型,如果可以使用相同的成員名稱,然後通過域運算符來訪問的話,該有多好!就像下面這樣:
color::red
但是這是舊版的enum無法做到的。
引入了域,要通過域運算符訪問,不可以直接通過枚舉體成員名來訪問(所以我們可以定義相同的枚舉體成員而不會發生重定義的錯誤)
#include <iostream>
enum class color { red, green, yellow};
enum class colorX { red, green, yellow };
int main() {
//使用域運算符訪問枚舉體成員,強轉後打印
std::cout << static_cast<int>(color::red) << std::endl;
std::cout << static_cast<int>(colorX::red) << std::endl;
std::cin.get();
return 0;
}
儘量用using而不是typedef
//typedef std::shared_ptr<FeatureInfo> FeatureInfo_Ptr;
using FeatureInfo_Ptr = std::shared_ptr<FeatureInfo>;
push_back(), 已知大小的情況下先reserve(),不需要隨機訪問的情況系下用list
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
memset
memset()函數原型是extern void *memset(void *buffer, int c, int count) buffer:爲指針或是數組,
c:是賦給buffer的值,
count:是buffer的長度.
int abs(int i); // 處理int類型的取絕對值
double fabs(double i); //處理double類型的取絕對值
float fabsf(float i); /處理float類型的取絕對值
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1、vector<Eigen::Matrix4d,Eigen::aligned_allocator<Eigen::Matrix4d>>
2、bitset
3、int*, static_cast<int*>, reinterpret_cast<int*>不一樣;
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
定義爲虛函數,繼承之後存在同名函數,但是行爲不同,可以使用基類指針或者引用指向;
BCD都繼承自A,可以使用A指針指向,從而做到用數組“保存”不同類型的BCD,不管是什麼類型,如果他們都存在與A的同名虛函數,那麼調用的就是BCD各自的方法,如果沒有定義爲虛函數,那麼在任何情況下調用的都是基類的方法;
如果不需要使用基類指針指向不同class,並調用同名函數,也沒必須定義虛函數,反正也不影響調用父類的函數功能
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------chrono計時:
std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
LandmarkFeatureExtracter::extract(scan, features);
GeometryFeatureExtracter::extract(scan, features);
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
std::chrono::steady_clock::duration used_time = end-start;
std::cout << "used time: " << std::chrono::duration_cast<std::chrono::milliseconds>(used_time).count() << std::endl;
https://www.cnblogs.com/bianchengnan/p/9478638.html