- 用vector创建数组对象
- vector数组是一个能存放任意数据类型(类,结构,普通变量类型等)的动态数组!
- 和普通数组一样可以通过下标索引来进行访问!
- 与其它动态序列容器相比(deques, lists and forward_lists), vector 在访问元素的时候更加高效,在末尾添加和删除元素相对高效。对于其它不在末尾的删除和插入操作,效率更低。比起lists和forward_lists统一的迭代器和引用更好。
- vector动态数组可以通过数组名进行直接赋值! vector c; vector b; b = c;
- 他的缺点:当新元素插入时候,这个数组需要被重新分配大小为了增加存储空间。其做法是,分配一个新的数组,然后将全部元素移到这个数组。就时间而言,这是一个相对代价高的任务,因为每当一个新的元素加入到容器的时候,vector并不会每次都重新分配大小。(比普通的数组具有更高的时间复杂度和空间复杂度)
- 用vector定义动态数组的形式为
vector<元素类型>数组对象 名(数组长度)
如:int x=10;
vectorarr(10); == int a[10];(常规方法定义一维数组)
== box(类名) *pt =new int [10](此处写的为用c++对象的动态建立) - 用vector数组对象元素的访问方式和普通数组具有相同的方式,但是vertor数组对象的名字表示的是一个数组对象而非数组的首地址,因为数组对象不是数组,而是封装了数组的对象,vector定义的数组对象具有一个重要的成员函数size(),它会返回数组的大小。
例子:参考如下
#include<isotream>
#include<vector>//voctor模板库
using namespace std;
//计算数组arr中元素的平均值
double average(const vector<double>&arr)
{
double sum=0;
for(unsigned i=0;i<arr.size();i++)//size()函数计算数组arr中元素的个数
{
sum+=arr[i];
return sum/arr.size();
}
}
int main()
{
unsigned n;
cout<<"n=";
cin>>n;
vector<double>arr(n);//创建数组对象
cout<<"please input "<<n<<"real numbers:"<<endl;
for(unsigned i=0;i<n;i++)
cin>>arr[i];
cout<<"Average="<<average(arr)<<endl;
return 0;
}
- 深拷贝和浅拷贝
浅拷贝:
所谓浅拷贝,指的是在对象复制时,只是对对象中的数据成员进行简单的赋值,上面的例子都是属于浅拷贝的情况,默认拷贝构造函数执行的也是浅拷贝。大多情况下“浅拷贝”已经能很好地工作了,但是一旦对象存在了动态成员,那么浅拷贝就会出问题了
class Rect
{
public:
Rect() // 构造函数,p指向堆中分配的一空间
{
p = new int(100);
}
~Rect() // 析构函数,释放动态分配的空间
{
if(p != NULL)
{
delete p;
}
}
private:
int width;
int height;
int *p; // 一指针成员
};
int main()
{
Rect rect1;
Rect rect2(rect1); // 复制对象
return 0;
}
在这段代码运行结束之前,会出现一个运行错误。原因就在于在进行对象复制时,对于动态分配的内容没有进行正确的操作
深拷贝:
在“深拷贝”的情况下,对于对象中动态成员,就不能仅仅简单地赋值了,而应该重新动态分配空间
class Rect
{
public:
Rect() // 构造函数,p指向堆中分配的一空间
{
p = new int(100);
}
Rect(const Rect& r)
{
width = r.width;
height = r.height;
p = new int; // 为新对象重新动态分配空间
*p = *(r.p);
}
~Rect() // 析构函数,释放动态分配的空间
{
if(p != NULL)
{
delete p;
}
}
private:
int width;
int height;
int *p; // 一指针成员
};
如何区分深拷贝与浅拷贝,简单点来说,就是假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝,拿人手短,如果B没变,那就是深拷贝,自食其力