1、push_back(实体对象):
传入的实体对象的地址&p1,将这个实体对象内的数据拷贝进新创建的对象中.这时并没有调用析构函数,也就是说原有的实体对象p1仍存在
2、push_back(参数):
push_back(参数)时,会首先调用测试类的有参构造函数,创建一个临时对象,然后再将这个临时对象所在的内存空间的地址作为右值传入测试类的右值构造函数中,测试类的右值构造会在容器内存中元素所在储存空间的末尾,创建一个新的对象,并通过地址,到临时对象所在的内存空间中,将里面的数据拷贝进新的对象里,完成添加操作。最后,临时对象的析构函数会被调用,这个对象将被析构,不再存在。
3.push_back( move(实体对象) )
与同样会调用测试类的右值构造函数的push_back(参数)的区别在于,push_back( move(实体对象) )在完成数据的拷贝后,不会调用析构函数析构右值所指示的那部分内存空间,也就是说,实体对象 p1 仍然存在,且指针 p1 所指示的内存空间内的值没有变化,仍然可以被访问。
4. emplace_back(实体对象)
emplace_back(实体对象),会调用测试类的拷贝构造函数,在容器末尾创建一个新的对象,并把实体对象p1的地址作为参数传入拷贝构造函数中,拷贝构造函数到达地址所指示的内存空间,将里面的数据拷贝到新创建的对象内,完成添加操作。操作完成后,同样没有析构函数被调用,也就是说原有实体对象 p1 仍然存在
5. emplace_back(参数)
emplace_back(10)并没有创建临时对象,最后析构临时对象的操作。而是调用测试类的有参构造函数,在容器的末尾直接创建一个新的对象,这时就完成添加操作了。
6. emplace_back( move(实体对象) )
与push_back( move(实体对象) )没有区别
总结:
push_back和emplace_back的区别只在传入的参数是对象的构造参数时,如push_back(10),emplace_back(10)。两种情况下: push_back(10)会先调用类的有参构造函数,创建一个临时对象,再在容器的末尾调用类的右值构造函数(因为这个临时对象没有名字,属于右值,所以只能使用右值构造函数),输入临时对象的地址,创建一个新的对象,根据地址值到临时对象所在的内存空间中拷贝数据,最后再调用临时对象的析构函数,析构这个临时对象。emplace_back(10)少了临时对象这一步,直接在容器的末尾调用类的有参构造函数创建一个新的对象,完成添加操作。