#include <iostream>
#include <vector>
#include <cstring>
#include <memory>
using namespace std;
//这个类没有写全。因为目的只是比较emplace和push。
//额。。。就算写全了我也不认为自己可以达到STL的水准。。。所以只挑跟主题相关的部分写了。。。
class m_string
{
public:
m_string()
{
_data=NULL;
len=0;
cout<<"default construct"<<endl;
}
m_string(const char * str)
{
len=strlen(str)+1;
_data=new char[len];
strcpy(_data,str);
cout<<"construct "<<endl;
}
m_string(const m_string & str)
{
len=strlen(str._data)+1;
_data=new char[len];
strcpy(_data,str._data);
cout<<"copy"<<endl;
}
//移动构造函数。与拷贝构造函数相比节省了一次内存分配的操作
m_string(m_string && str)
{
_data=str._data;
len=str.len;
str._data=NULL;
str.len=0;
cout<<"move"<<endl;
}
~m_string()
{
//因本例关注的是拷贝&构造等,为避免输出干扰,未打印析构信息
//cout<<"destruct"<<endl;
if(_data!=NULL)
{
delete[] _data;
}
}
private:
char * _data;
int len;
};
//测试push一个有名对象。-->表现跟C++03一致,先构造对象,再copy。(!注意copy的代价)
void test_push_named_obj( )
{
cout<<"push _named_obj"<<endl;
vector<m_string> cols;
m_string obj("abc");
cols.push_back(obj);
cout<<endl<<endl;
}
//测试push一个匿名对象。-->先构造对象,再move。省去了copy的代价
void test_push_unnamed_obj( )
{
cout<<"push _unnamed_obj"<<endl;
vector<m_string> cols;
cols.push_back("abc");
cout<<endl<<endl;
}
//测试emplace一个有名对象 -->表现跟C++的push一致,先构造,再copy (!注意copy的代价)
void test_emplace_named_obj( )
{
cout<<"emplace _named_obj"<<endl;
vector<m_string> cols;
m_string obj("abc");
cols.emplace_back(obj);
cout<<endl<<endl;
}
//测试emplace一个匿名对象。-->直接在目标内存区域构造,不但省去了copy,连move的代价都省去了。
void test_emplace_unnamed_obj( )
{
cout<<"emplace _unnamed_obj"<<endl;
vector<m_string> cols;
cols.emplace_back("abc");
cout<<endl<<endl;
}
void test_fun()
{
test_push_named_obj();
test_push_unnamed_obj();
test_emplace_named_obj();
test_emplace_unnamed_obj();
}
int main()
{
test_fun();
return 0;
#include <vector>
#include <cstring>
#include <memory>
using namespace std;
//这个类没有写全。因为目的只是比较emplace和push。
//额。。。就算写全了我也不认为自己可以达到STL的水准。。。所以只挑跟主题相关的部分写了。。。
class m_string
{
public:
m_string()
{
_data=NULL;
len=0;
cout<<"default construct"<<endl;
}
m_string(const char * str)
{
len=strlen(str)+1;
_data=new char[len];
strcpy(_data,str);
cout<<"construct "<<endl;
}
m_string(const m_string & str)
{
len=strlen(str._data)+1;
_data=new char[len];
strcpy(_data,str._data);
cout<<"copy"<<endl;
}
//移动构造函数。与拷贝构造函数相比节省了一次内存分配的操作
m_string(m_string && str)
{
_data=str._data;
len=str.len;
str._data=NULL;
str.len=0;
cout<<"move"<<endl;
}
~m_string()
{
//因本例关注的是拷贝&构造等,为避免输出干扰,未打印析构信息
//cout<<"destruct"<<endl;
if(_data!=NULL)
{
delete[] _data;
}
}
private:
char * _data;
int len;
};
//测试push一个有名对象。-->表现跟C++03一致,先构造对象,再copy。(!注意copy的代价)
void test_push_named_obj( )
{
cout<<"push _named_obj"<<endl;
vector<m_string> cols;
m_string obj("abc");
cols.push_back(obj);
cout<<endl<<endl;
}
//测试push一个匿名对象。-->先构造对象,再move。省去了copy的代价
void test_push_unnamed_obj( )
{
cout<<"push _unnamed_obj"<<endl;
vector<m_string> cols;
cols.push_back("abc");
cout<<endl<<endl;
}
//测试emplace一个有名对象 -->表现跟C++的push一致,先构造,再copy (!注意copy的代价)
void test_emplace_named_obj( )
{
cout<<"emplace _named_obj"<<endl;
vector<m_string> cols;
m_string obj("abc");
cols.emplace_back(obj);
cout<<endl<<endl;
}
//测试emplace一个匿名对象。-->直接在目标内存区域构造,不但省去了copy,连move的代价都省去了。
void test_emplace_unnamed_obj( )
{
cout<<"emplace _unnamed_obj"<<endl;
vector<m_string> cols;
cols.emplace_back("abc");
cout<<endl<<endl;
}
void test_fun()
{
test_push_named_obj();
test_push_unnamed_obj();
test_emplace_named_obj();
test_emplace_unnamed_obj();
}
int main()
{
test_fun();
return 0;
}
输出结果:
push _named_obj
construct
copy
push _unnamed_obj
construct
move
emplace _named_obj
construct
copy
emplace _unnamed_obj
construct