序:
我们在使用vector的时候可以自定义里面的数据类型。例如这样:
struct Edge{
int from;
int to;
int weight;
};
vector<Edge> edge;
使用vector的使用我们有时会用到resize和reserve函数进行内存的分配。在之前的测试中我们发现先使用resize再用下标访问读取数据的效率要远远高于push_back()(测试结果见下),所以resize函数在初始化的时候会被使用。
关于vector push_back()与其他方式读取数据的效率对比
但是当我们真的调用resize函数的时候,编译器会报错:
edge.resize(0);
---
[Error] no matching function for call to 'Edge::Edge()'
[Note] candidates are:
难道是调用resize的时候格式出了问题吗?
但是却发现下面的:
vector<int> arc[maxn];
arc[i].resize(0);
却没有任何问题。
那么自定义结构体与int这类数据类型到底哪里不同?
后来我们发现加上它就不会报错了:
struct Edge{
int from;
int to;
int weight;
Edge(){} /* 重点在这里 */
Edge(int f, int t, int w):
from(f), to(t), weight(w){}/* 这个不是重点 */
};
原来当执行resize的时候,如果我们将它扩大,编译器会自动将剩下的部分初始化。int的初始化为0,但是我们自定义的结构体没有初始化函数。所以它无法执行。
类似的,当我们直接声明一个结构体数组的时候:
Edge edge[maxn];
发生报错的原因也在于此,由于vector在声明的时候不会执行初始化所以没有报错。但是声明一个数组,编译器会将整个数组初始化,这就需要你手写一个初始化的函数。(可以是空,也可以在里面写你要的特殊初始化,但是必须要有)而且这个初始化的函数参数是空的,函数名就是结构体的名字(你初始化的时候没有参数),跟普通的函数一个意思,只不过是写在了结构体的内部。
那么再看下面不是重点的那两行代码:
Edge(int f, int t, int w):
from(f), to(t), weight(w){}
这个就是有参数的初始化了。当你读入多个数据构造结构体的时候,这样做会让代码很简洁。
不用的话是这样的:
n = Get_Int(), m = Get_Int(), we = Get_Int();//读入优化
edge[i].from = n;
edge[i].to = m;
...
有了它代码会是这样的:
n = Get_Int ...; /* 输入同上 */
edge[i] = Edge(n, m, we);
明显简洁了很多。
自此结束。
箜瑟_qi 2017.04.22 11:35