#include
#include
#include
using namespace std;
class Animal
{
public:
Animal(string name)
{
this->name = name;
cout<<"struct"<<endl;
}
Animal()
{
cout<<"default-struct"<<endl;
}
~Animal()
{
}
Animal(const Animal & T)
{
this->name = T.name;
cout<<"copy:"<<T.name<<endl;
}
void speak()
{
cout<<"my name is "<<name<<endl;
}
void set(string name)
{
this->name = name;
}
private:
string name;
};
int main()
{
Animal T1("xx1");
Animal T2("xx2");
Animal T3("xx3");
Animal T4("xx4");
Animal T5("xx5");
Animal T6("xx6");
vector<Animal> t_vObject;
//t_vObject.clear();
t_vObject.push_back(T1);
t_vObject.push_back(T2);
t_vObject.push_back(T3);
t_vObject.push_back(T4);
t_vObject.push_back(T5);
t_vObject.push_back(T6);
}
由结果可见在构造animal对象时,会调用构造函数,在往vector里面装对象时,调用了拷贝构造函数,说明vector里面存放对象时,是将原来的对象进行了复制,由打印的情况来看,进行了多次复制,进行探究后发现是因为vector扩容时会将之前的部分进行复制,所以每一次扩容就会进行一个整体复制。我们改进代码:进行初始大小设定
int main()
{
Animal T1("xx1");
Animal T2("xx2");
Animal T3("xx3");
Animal T4("xx4");
Animal T5("xx5");
Animal T6("xx6");
vector<Animal> t_vObject(10);
t_vObject.clear();
t_vObject.push_back(T1);
t_vObject.push_back(T2);
t_vObject.push_back(T3);
t_vObject.push_back(T4);
t_vObject.push_back(T5);
t_vObject.push_back(T6);
}
我们给容器一个初始大小,然后将容器清空,此时容器就有了十个大小的容量,再往里面装对象时,就不会出现多次扩容的情况。
int main()
{
Animal *dog=new Animal("dog");
Animal *cat=new Animal("cat");
Animal *panda=new Animal("panda");
vector<Animal*> t_vAnimals(10);
t_vAnimals.push_back(cat);
t_vAnimals.push_back(dog);
t_vAnimals.push_back(panda);
vector<Animal*> t_vAnimalscopy = t_vAnimals;
for (int i=0; i< t_vAnimalscopy.size(); i++)
{
t_vAnimalscopy[i] = nullptr;
}
t_vAnimalscopy.clear();
int num = t_vAnimalscopy.size();
cout<<"t_vAnimalscopy.size() ="<<num<<endl;
int num2 = t_vAnimals.size();
cout<<"t_vAnimals.size() ="<<num2<<endl;
for (int i=0;i< t_vAnimals.size(); i++)
{
if (t_vAnimals[i] == nullptr)
{
cout<<"pointer is null"<<endl;
continue;
}
t_vAnimals[i]->speak();
}
}
由打印结果可见,在构造对象指针时,只会在new的时候调用构造函数。在对容器里面装指针时,应该也是进行了指针变量的复制,但是指针变量指向的地址是相同的,然后我们对容器进行复制后发现,在进行容器复制时,也是进行了变量的复制。由结果可见复制的大小已经为空了,但是原来的还能正常speak,说明地址的内容还在。
我们将复制的那一份数据擦除掉,即在遍历时,将里面的每一个数据都进行delete。最后得到初始的容器里的那一份数据会出现指针错误的提示,这说明,他们的地址是一样的,调用delete释放了那一块内存,此时会自动调用析构函数,也就是对象也就没了。
Animal *dog=new Animal("dog");
Animal *cat=new Animal("cat");
Animal *panda=new Animal("panda");
vector<Animal*> t_vAnimals(10);
t_vAnimals.push_back(cat);
t_vAnimals.push_back(dog);
t_vAnimals.push_back(panda);
vector<Animal*> t_vAnimalscopy = t_vAnimals;
for (int i=0; i< t_vAnimalscopy.size(); i++)
{
delete t_vAnimalscopy[i];
t_vAnimalscopy[i] = nullptr;
}
t_vAnimalscopy.clear();
int num = t_vAnimalscopy.size();
cout<<"t_vAnimalscopy.size() ="<<num<<endl;
int num2 = t_vAnimals.size();
cout<<"t_vAnimals.size() ="<<num2<<endl;
for (int i=0;i< t_vAnimals.size(); i++)
{
if (t_vAnimals[i] == nullptr)
{
cout<<"pointer is null"<<endl;
continue;
}
t_vAnimals[i]->speak();
}
我们通过变量复制的那一份数据,对对象的名字进行更改,然后变量原始的数据容器,打印他们只向的对象的名字,发现名字已经被修改,说明他们指向的是同一个地址。
int main()
{
Animal *dog=new Animal("dog");
Animal *cat=new Animal("cat");
Animal *panda=new Animal("panda");
vector<Animal*> t_vAnimals;
t_vAnimals.push_back(cat);
t_vAnimals.push_back(dog);
t_vAnimals.push_back(panda);
vector<Animal*> t_vAnimalscopy = t_vAnimals;
for (int i=0; i< t_vAnimalscopy.size(); i++)
{
t_vAnimalscopy[i]->set("coco");
}
for (int i=0;i< t_vAnimals.size(); i++)
{
if (t_vAnimals[i] == nullptr)
{
cout<<"pointer is null"<<endl;
continue;
}
t_vAnimals[i]->speak();
}
getchar();
}
在往容器里面装数据时,数据会进行复制。若数据为对象,则会调用对象的复制构造函数。若对象时指针则不会调用复制构造函数,此时复制的的指针变量,只不过变量指向的地址是一样的。对容器进行清空,调用delete会释放对象,同时调用析构函数。对复制的指针数据进行修改,原始的数据也会修改,说明复制对象指针时,其实只有一份数据。