分享

关于vector存放对象和对象指针的探索_vector放对象指针

 wuxinit_ 2023-11-07 发布于湖北

1 vector容器里存放对象

#include <iostream>
#include <string>
#include <vector>
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);

}

运行截图

结论1.1

由结果可见在构造animal对象时,会调用构造函数,在往vector里面装对象时,调用了拷贝构造函数,说明vector里面存放对象时,是将原来的对象进行了复制,由打印的情况来看,进行了多次复制,进行探究后发现是因为vector扩容时会将之前的部分进行复制,所以每一次扩容就会进行一个整体复制。我们改进代码:进行初始大小设定

改进1.2

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);
}

我们给容器一个初始大小,然后将容器清空,此时容器就有了十个大小的容量,再往里面装对象时,就不会出现多次扩容的情况。
运行截图

2 vector容器里存放对象指针

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();
	}
}

结果2.1

由打印结果可见,在构造对象指针时,只会在new的时候调用构造函数。在对容器里面装指针时,应该也是进行了指针变量的复制,但是指针变量指向的地址是相同的,然后我们对容器进行复制后发现,在进行容器复制时,也是进行了变量的复制。由结果可见复制的大小已经为空了,但是原来的还能正常speak,说明地址的内容还在。
运行截图

探究2.2

我们将复制的那一份数据擦除掉,即在遍历时,将里面的每一个数据都进行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();
	}

运行截图

运行截图

验证2.3

我们通过变量复制的那一份数据,对对象的名字进行更改,然后变量原始的数据容器,打印他们只向的对象的名字,发现名字已经被修改,说明他们指向的是同一个地址。

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();
	
}

运行截图

3总结

在往容器里面装数据时,数据会进行复制。若数据为对象,则会调用对象的复制构造函数。若对象时指针则不会调用复制构造函数,此时复制的的指针变量,只不过变量指向的地址是一样的。对容器进行清空,调用delete会释放对象,同时调用析构函数。对复制的指针数据进行修改,原始的数据也会修改,说明复制对象指针时,其实只有一份数据。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多