C++ 容器 push_back 和 emplace_back

C++ 容器 push_back 和 emplace_back

根据 《C++ Primer 5-th》P308 的解释,push_back() 是拷贝对象,而 emplace_back() 是构造对象

emplace_back() 直接在 容器中构造对象的方式 性能更优,可以减少内存拷贝

1. 类类型代码

class T
{
	int a = 1;
	int b = 2;
	string s;

public:
	T() { cout << "默认构造函数" << endl; };  // 默认构造函数
	T(int _a , int _b = 200, string _s = "good") :a(_a), b(_b), s(_s) { cout << "构造函数1" << endl; };
	T(string _s) :s(_s) { cout << "构造函数2" << endl; }

	T(const T& t) :a(t.a), b(t.b), s(t.s) { cout << "拷贝构造" << endl; }

	void show()
	{
		cout << "a = " << a << '\t' << "b = " << b << "\t" << "s = " << s << endl;
	}
};

设计好几个构造函数和一个拷贝构造函数进行测试

2. 创建容器

创建容器 vector,提前预留足够空间

注意一定要先 预申请足够的空间, 否则空间不够时, vector 就会重新申请空间, 然后 转移元素, 转移的时候元素在新旧空间之间发生拷贝, 这就会调用 拷贝构造函数, 从而影响这里 emplace_back 和 push_back 的判断

vector 内存大小管理

vector<T> test;
test.reserve(10);  

3. 调用 push_back()

3.1 先创建对象,再 push_back

T t1(10, 20, "t1");                  // 构造函数1

test.push_back(t1);                  // 拷贝构造

3.2 直接创建临时对象传递给 push_back

test.push_back(1, 2, "t2");         // 报错, 必须传入类对象
test.push_back(T(1, 2, "t2"));      // 构造函数1  拷贝构造
test.push_back(T("t3"));            // 构造函数2  拷贝构造

可以看到,push_back 必须传入类的对象,也就是先创建对象(占用内存),然后把这个对象 拷贝 到容器空间中

4. 调用 emplace_back()

test.emplace_back(100, 200, "t3");  // 构造函数1
test.emplace_back("t4");           // 构造函数2
test.emplace_back();               //默认构造函数

emplace_back 不需要类的对象,直接在容器空间中创建对象,节省了空间,而且少一次拷贝

test.emplace_back(T(100, 200, "t3"));   // 构造函数1 拷贝构造
test.emplace_back(T("t4"));             // 构造函数2   拷贝构造
T tt(10, 20, "tt");                  // 构造函数1
test.emplace_back(tt);               // 拷贝构造

测试发现,emplace_back 也可以传入 类对象,但是此时就会退化成 push_back()

5. 其它测试代码

int main()
{

	vector<T> test;

	test.reserve(10);    
	// 注意一定要先 预申请足够的空间, 否则空间不够时, vector 就会重新申请空间, 然后 转移元素, 转移的时候会发生元素在新旧空间的拷贝, 这会调用 拷贝构造函数, 影响这里 emplace_back 和 push_back 的判断

	T t1(10, 20, "t1");                  // 构造函数1

	cout << endl;
	cout << "########### 测试 push_back ###########" << endl << endl;

	test.push_back(t1);                 // 拷贝构造
	cout << endl;

	test.push_back(T(1, 2, "t2"));      // 构造函数1  拷贝构造
	cout << endl;
	
	cout << "########### 测试 emplace_back ###########" <<endl<< endl;
	
	test.emplace_back(100, 200, "t3");  // 构造函数1
	cout << endl;
	
	test.emplace_back("t4");           // 构造函数2
	cout << endl;
	
	test.emplace_back();               //默认构造函数
	cout << endl;

	return 0;
	
}

你可能感兴趣的:(c++)