本身是实现一个Trie树,本身难度不大,主要是很久没写C++了,重拾之后,发现了很多有意思的东西。
什么是lvalue和rvalue? lvalue就是能取到地址的变量。而rvalue是临时变量。例如i是lvalue,而99是rvalue:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #include <iostream> void f (int & i) { std::cout << "lvalue ref: " << i << "\n" ; }void f (int && i) { std::cout << "rvalue ref: " << i << "\n" ; }int main () { int i = 77 ; f (i); f (99 ); f (std::move (i)); return 0 ; }
再看个例子:getValue函数的返回值是rvalue
1 2 3 4 5 6 7 8 9 10 11 12 13 #include <iostream> int getValue () { int ii = 10 ; return ii; }int main () { std::cout << getValue (); return 0 ; }
1 2 const int & val = getValue(); int & val = getValue();
而现在可以通过rvalue引用(mutable)来引用该变量,甚至可以修改:
1 2 const int && val = getValue (); int && val = getValue ();
除此之外,可以通过overload来判断lvalue还是rvalue:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 #include <iostream> using namespace std;void printReference (int & value) { cout << "lvalue: value = " << value << endl; } void printReference (int && value) { cout << "rvalue: value = " << value << endl; }int getValue () { int temp_ii = 99 ; return temp_ii; }int main () { int ii = 11 ; printReference (ii); printReference (getValue ()); return 0 ; }
总结:
C++11引入int &&a
来声明rvalue引用
rvalue绑定的通常会是临时对象
什么是std::move,作用是什么? 参考C++ Tutorial: C++11/C++14 5. rvalue Reference and Move Semantics - 2017 (bogotobogo.com) ,move()的作用是将lvalue转化为rvalue。
在C++11之前,在以传值的方式传参的时候,发生了很多implicit copy。现在我们可以通过overloading来区分传入的参数的permanent(lvalue) 还是temporary(rvalue), 从而避免copy。
当传入的参数是rvalue的时候,我们知道其很快就销毁了,所以我们不需要重新申请空间然后拷贝,我们只需要用rvalue的空间就行。
Move Constructor 1 2 3 4 5 A (A&& other) noexcept { mData = other.mData; other.mData = nullptr ; }
Move Assignment Operator 1 2 3 4 5 6 A& operator =(A&& other) noexcept { mData = other.mData; other.mData = nullptr ; return *this ; }
比起Move Constructor,赋值Operator由于本来就存在值,因此多了一步,一共四步:
释放当前自己拥有的资源
将other的资源拿过来(而非copy)
将other的资源清空
返回*this
智能指针 自动释放空间的指针,参考smart pointers - cppreference.com ,例如:
1 2 3 4 5 6 7 8 9 10 void my_func () { int * valuePtr = new int (15 ); int x = 45 ; if (x == 45 ) return ; delete valuePtr; }
我们需要在return之前delete,不然会有内存泄露。而使用智能指针后,就没有这个问题了:
1 2 3 4 5 6 7 8 9 void my_func () { std::unique_ptr<int > valuePtr (new int (15 )) ; int x = 45 ; if (x == 45 ) return ; }
unique_ptr 被其管理的对象只能有这一个指针指着。该指针无了之后,对象就可以被回收了。智能指针的使用与普通指针相同。创建与清空不同:
1 2 3 4 std::unique_ptr<int > valuePtr (new int (47 )) ; valuePtr.reset ();
unique_ptr支持move,但不支持copy,因为copy后就不再只有唯一指针指着了对象了。例如:
1 2 std::unique_ptr<int > valuePtr (new int (15 )) ;std::unique_ptr<int > valuePtrNow (std::move(valuePtr)) ;
shared_ptr 支持多个指针指着,当计数器为0时,自动delete。