C++11新特性——emplace




emplace操作是C++11新特性,新引入的的三个成员emlace_front、empace 和 emplace_back,这些操作构造而不是拷贝元素到容器中,这些操作分别对应push_front、insert 和push_back,允许我们将元素放在容器头部、一个指定的位置和容器尾部。

两者的区别 

当调用insert时,我们将元素类型的对象传递给insert,元素的对象被拷贝到容器中,而当我们使用emplace时,我们将参数传递元素类型的构造函,emplace使用这些参数在容器管理的内存空间中直接构造元素。

一个例子

MyString.h

  1. #ifndef MYSTRING_H
  2. #define MYSTRING_H
  3. #include <iostream>
  4. class MyString
  5. {
  6. public:
  7. MyString(const char *str = NULL);// 普通构造函数
  8. MyString(const MyString &other);// 拷贝构造函数
  9. ~MyString(void);// 析构函数
  10. MyString & operator = (const MyString &other);// 赋值函数
  11. private:
  12. char *m_data;// 用于保存字符串
  13. };
  14. #endif // MYSTRING_H

MyString.cpp

  1. #include "MyString.h"
  2. #include <iostream>
  3. #include <string.h>
  4. //普通构造函数
  5. MyString::MyString(const char *str)
  6. {
  7. if (str == NULL)
  8. {
  9. m_data = new char[1];
  10. *m_data = '\0';
  11. }
  12. else
  13. {
  14. int length = strlen(str);
  15. m_data = new char[length + 1];
  16. strcpy(m_data, str);
  17. }
  18. std::cout<<"construct:"<<m_data<<std::endl;
  19. }
  20. // String的析构函数
  21. MyString::~MyString(void)
  22. {
  23. std::cout<<"deconstruct:"<<m_data<<std::endl;
  24. delete[] m_data;
  25. }
  26. //拷贝构造函数
  27. MyString::MyString(const MyString &other)
  28. {
  29. int length = strlen(other.m_data);
  30. m_data = new char[length + 1];
  31. strcpy(m_data, other.m_data);
  32. std::cout<<"copy construct:"<<m_data<<std::endl;
  33. }
  34. //赋值函数
  35. MyString & MyString::operator = (const MyString &other)
  36. {
  37. std::cout<<"copy assignment"<<std::endl;
  38. if (this == &other)
  39. return *this;
  40. if (m_data)
  41. delete[] m_data;
  42. int length = strlen(other.m_data);
  43. m_data = new char[length + 1];
  44. strcpy(m_data, other.m_data);
  45. return *this;
  46. }

main.cpp

  1. #include <vector>
  2. #include "MyString.h"
  3. int main()
  4. {
  5. {
  6. std::cout<<"++++++++++++++++++++++++++++++++++"<<std::endl;
  7. std::vector<MyString> vStr;
  8. // 预先分配,否则整个vector在容量不够的情况下重新分配内存
  9. vStr.reserve(100);
  10. vStr.push_back(MyString("can ge ge blog"));
  11. }
  12. {
  13. std::cout<<"++++++++++++++++++++++++++++++++++"<<std::endl;
  14. std::vector<MyString> vStr;
  15. // 预先分配,否则整个vector在容量不够的情况下重新分配内存
  16. vStr.reserve(100);
  17. vStr.emplace_back("hello world");
  18. }
  19. system("pause");
  20. return 0;
  21. }

输出结果


从结果可以看出,vStr.push_back(MyString("can ge ge blog")) 这个语句首先执行了构造函数,构造一个临时对象,接着执行拷贝构造将临时对象复制到vector,最后销毁临时对象和vector中的元素。而emplace_back只调用一次构造函数和一次析构函数。两相对比,效率上的提高不言而喻


posted @ 2019-05-19 21:57  unique_ptr  阅读(1235)  评论(0)    收藏  举报