&
.&&
.
void Testreference1()
{
//以下的p、b、c、*p都是左值
//可以取到地址的变量
int* p = new int(0);
int b = 1;
const int c = 2;
//以下几个是对上面左值的左值引用
int* & rp = p;
int & rb = b;
const int & rc = c;
int & pvalue = *p;
}
void Testreference2()
{
double x = 1.1, y = 2.2;
//以下几个都是对右值的右值引用
//常量
int&& rr1 = 10;
//表达式返回值
double&& rr2 = (x + y);
//非const修饰的函数返回值(fmin返回值为double)
double&& rr3 = fmin(x, y);
}
const type&
(被const限定的左值引用)既可以引用左值,也可以引用右值namespace mystring
{
class string
{
public:
//构造函数(深拷贝)
string(const char* str = "")
:_size(strlen(str))
,_capacity(_size)
{
_str = new char[_capacity + 1];
strcpy(_str, str);
}
//交换两个string对象(堆区资源交换)
void swap(string& s)
{
std::swap(_str, s._str);
std::swap(_size, s._size);
std::swap(_capacity, s._capacity);
}
//拷贝构造(复用构造函数实现)(深拷贝)
string(const string& s)
:_str(nullptr)
{
cout << "string(const string& s) -- 拷贝构造(深拷贝)" << endl;
string tmp(s._str);
swap(tmp);
}
//赋值重载(复用拷贝构造实现)(深拷贝)
string& operator=(const string& s)
{
cout << "string& operator=(string s) -- 赋值重载(深拷贝)" << endl;
string tmp(s);
swap(tmp);
return *this;
}
//析构函数
~string()
{
delete[] _str;
_str = nullptr;
}
private:
char* _str;
size_t _size;
size_t _capacity;
};
}
string to_string()
{
string tem("对象测试");
return tem;
}
//tem在函数调用完后就是一个即将析构的对象
int main()
{
string s(to_string());
return 0;
}
namespace mystring
{
class string
{
public:
//构造函数
string(const char* str = "")
:_size(strlen(str))
,_capacity(_size)
{
_str = new char[_capacity + 1];
strcpy(_str, str);
}
//交换两个string对象(堆区资源交换)
void swap(string& s)
{
std::swap(_str, s._str);
std::swap(_size, s._size);
std::swap(_capacity, s._capacity);
}
//拷贝构造(复用构造函数实现)
string(const string& s)
:_str(nullptr)
{
cout << "string(const string& s) -- 拷贝构造(深拷贝)" << endl;
string tmp(s._str);
swap(tmp);
}
//赋值重载(复用拷贝构造实现)
string& operator=(const string& s)
{
cout << "string& operator=(string s) -- 赋值重载(深拷贝)" << endl;
string tmp(s);
swap(tmp);
return *this;
}
//移动构造
string(string && s)
:_str(nullptr)
, _size(0)
, _capacity(0)
{
_str = new char[_capacity + 1];
cout << "string(string&& s) -- 移动构造(资源转移)" << endl;
swap(s);
}
//移动赋值
string& operator=(string && s)
{
cout << "string& operator=(string&& s) -- 移动赋值(资源转移)" << endl;
swap(s);
return *this;
}
//析构函数
~string()
{
delete[] _str;
_str = nullptr;
}
private:
char* _str;
size_t _size;
size_t _capacity;
};
}
string to_string()
{
string tem("对象测试");
return tem;
}
//tem在函数调用完后就是一个即将析构的对象
int main()
{
//函数返回值被识别成右值,调用移动构造交换堆区资源,避免了深拷贝
string s(to_string());
return 0;
}
string to_string()
{
string tem("对象测试");
return tem;
}
//tem在函数调用完后就是一个即将析构的对象
int main()
{
string s;
s = to_string();
return 0;
}
int main()
{
//测试构造函数
string s1("对象测试");
//s1是左值对象,调用拷贝构造
string s2(s1);
//move强制让编译器将s1识别成右值,调用移动构造交换堆区资源
string s3(std::move(s1));
cout << endl;
//测试赋值重载函数
//函数返回值被识别成右值,调用移动赋值交换堆区资源,避免了深拷贝
string s4("对象测试");
//s4是左值对象,调用赋值重载
s2 = s4;
//move强制让编译器将s1识别成右值,调用移动赋值,交换堆区资源
s3 = std::move(s1);
}
template<typename T>
void PerfectForward(T&& t)
{
}
std::forward
函数来辅助引用参数传递(称为完美转发):int main()
{
string s1("对象测试");
list<string> List;
List.push_back(std::move(s1));
}
push_back
接口的内部代码结构:template<class T>
struct ListNode
{
ListNode* _next = nullptr;
ListNode* _prev = nullptr;
T _data;
};
template<class T>
class list
{
typedef ListNode<T> Node;
public:
//复用Insert实现
void push_back(T&& x)//引用折叠
{
//引用完美转发
Insert(_head, std::forward<T>(x));
}
//链表结点插入接口
void Insert(Node* pos, T&& x)//引用折叠
{
Node* prev = pos->_prev;
Node* newnode = new Node;
//引用完美转发
newnode->_data = std::forward<T>(x);
prev->_next = newnode;
newnode->_prev = prev;
newnode->_next = pos;
pos->_prev = newnode;
}
private:
Node* _head;
};