在cpp 中vector存储类的时候,什么时候调用构造函数,什么时候调用拷贝构造,什么时候调用等号,这个问题值得测试了解一下
首先写一个类 FaceInfo.h
#pragma once
class FaceInfo
{
public:
FaceInfo();
~FaceInfo();
FaceInfo & operator=(const FaceInfo &another);
FaceInfo(const FaceInfo &another);
int * data = 0;
int len = 100;
int index = 0;
};
FaceInfo.cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "FaceInfo.h"
FaceInfo::~FaceInfo()
{
if (data)
{
delete[] data;
data = 0;
}
printf("~~~~~FaceInfo .... \n");
}
FaceInfo::FaceInfo()
{
data = new int[len];
printf("FaceInfo .... \n");
}
FaceInfo::FaceInfo(const FaceInfo &another)
{
printf("拷贝构造 .... \n");
//拷贝构造
this->index = another.index;
this->data = new int[len];
memcpy(this->data, another.data, len * sizeof(int));
}
FaceInfo & FaceInfo::operator=(const FaceInfo &another)
{
printf("FaceInfo operator = \n");
// 1.防止自身赋值
if (this == &another)
{
return *this;
}
// 2. 给自己额外开辟的内存空间释放掉
if (this->data != NULL)
{
delete[] this->data;
this->data = NULL;
}
//3. 执行深拷贝
this->index = another.index;
this->data = new int[len];
memcpy(this->data, another.data, len * sizeof(int));
return *this;
}
测试代码main.cpp
#include <stdio.h>
#include <vector>
#include <iostream>
#include "FaceInfo.h"
FaceInfo getFaceInfo()
{
FaceInfo mFaceInfo;
mFaceInfo.data[0] = 521;
printf("getFaceInfo....... \n");
return mFaceInfo;
}
int main()
{
printf("hello world \n");
FaceInfo mFaceInfo;
std::vector<FaceInfo> mVec;
mVec.reserve(10);
for (int i = 0; i < 5; i++)
{
mFaceInfo.index = i;
mVec.push_back(mFaceInfo); // 拷贝构造
}
//mVec.resize(2); // 会掉用三个析构函数
//FaceInfo mFaceInfo1 = mFaceInfo; // 调用拷贝构造
//FaceInfo mFaceInfo1; mFaceInfo1 = getFaceInfo(); // 先构造,后=
FaceInfo mFaceInfo1 = getFaceInfo(); //不算函数里面,只调用拷贝构造,本以为还会掉=,然而并没有
//printf("mFaceInfo1.data[0]=%d \n", mFaceInfo1.data[0]);
std::cout << "mVec.size = " << mVec.size() << std::endl;
std::vector<FaceInfo>::iterator iter = mVec.begin();
for (; iter != mVec.end(); iter++)
{
printf(" index = %d ... \n", iter->index);
}
mVec.erase(mVec.begin()); // 会把第一个析构,后面四个前移,调用等号表达
std::cout << "mVec.size = " << mVec.size() << std::endl;
std::cout << "mVec.cap = " << mVec.capacity() << std::endl;
printf("mvec[0].index=%d \n", mVec[0].index);
}
结论是:好吧,你看代码注释就知道了,还是啰嗦一下
1:FaceInfo mFaceInfo1 = mFaceInfo; // 调用拷贝构造,本以为会有=
2:FaceInfo mFaceInfo1; mFaceInfo1 = getFaceInfo(); // 先构造,后=
3:FaceInfo mFaceInfo1 = getFaceInfo(); // 类似1,调用拷贝
4:mVec.erase(mVec.begin()); // 会把第一个析构,后面四个前移,调用4次等号表达
惊不惊喜