我已经阅读了关于“指针”的主题,但我还是有一些问题。
// graph.cpp
struct Edge {
int from;
int to;
unsigned int id;
Edge(): from(0), to(0), id(0) {};
};
struct Vertex {
int label;
vector<Edge> edge;
};
class Graph: public vector<Vertex> {
int gid;
unsigned int edge_size;
};
如果我在另一个文件中声明一个迭代器
bool get_forward_root (Graph &g, Vertex &v, vector<Edge*> &result) {
for(vector<Edge>::iterator it = v.edge.begin(); it != v.edge.end(); it++) {
if(v.label <= g[it->to].label)
result.push_back(&(*it));
}
}
据我了解,it
可以被视为指针,因为v.edge.begin()
是Edge
中的第一个vector<Edge>
对象,但&(*it)
是什么? / p>
问题2. g
,&g
,*g
之间的区别是什么?
根据我的理解:
&g
是内存地址。*g
是指向图形对象的Graph指针,因此我们可以使用Graph * g = new Graph(); g
是图表对象* g和g之间的差异是我们使用的方式,例如两个条件是相同的:
条件1:
Graph *g = new Graph();
g->gid = 0;
条件2:
Graph g;
g.gid = 0;
问题3。
以下是什么意思?
Graph &g
以及为什么我们使用g[it->to].label
而不是&g[it->to].label
非常感谢:)
答案 0 :(得分:5)
问题1:什么是&amp;(* it)
it
就像一个指针,但它不是一个指针。如果它是指针,&*it
将与it
相同。在一般情况下,&(*it)
是迭代器it
指向的对象的地址(实际指针)。我们可以在这里假设&amp;操作员没有超载。
问题2:g,&amp; g,* g?
之间有什么区别?
g
是g
。 &g
是g的地址。 *g
是指向g
的对象(如果g是指针)。你的两个条件(我不明白为什么你称之为条件)做同样的事情,是的。
问题3:什么是
Graph &g?
它被称为参考。定义时,应立即初始化。将引用视为对象的另一个名称。 (更好的是,读一本书,见下文)。
所有问题都将在任何体面的C ++初学者书籍中得到彻底解答。为此,我特别推荐Lippman的C ++入门。找到其他好的标题here。
答案 1 :(得分:1)
it
不是指针,它是迭代器。基本上它的行为就像一个指针(取消引用和箭头操作符被重载),也像数组索引(++
,--
,+=
等,推进迭代器指向下一个元素对于矢量,你可能会觉得没用,但这对其他容器来说很棒。)
因此,&(*it)
将迭代器转换为实际指针:它获取指向对象的地址。但它对矢量没有太大影响,因为所有元素都存储在连续的存储区中。
答案 2 :(得分:1)
问题1:it
不是指针,它是迭代器。迭代器表现得很好
有点像指针,仅限某些东西,但它们不是
指针。在表达式&(*it)
中,*
取消引用迭代器,以获取
对其指定的实际对象的引用;然后&
接受
该对象的地址,它产生一个带指针的实际指针
type(容器result
需要的内容)。
问题2:g
是对象的名称;在表达中,它
指定对象,并具有对象的类型。 &g
是
对象的地址;一个物体本身(尽管是暂时的)有一个
指针类型。 *g
不合法。至少只要没有用户定义
运算符发挥作用:类型Graph
可能超载operator*
或
operator&
要做更多或更少的事情。 (举个例子,有
g[it->to]
,很明显Graph
重载[]
;这意味着
通常的身份a[b]
意味着*(a+b)
不成立。)并且在你的身上
代码,g
不是指向Graph
的指针,它是一个引用,
就像一个别名 - 用于初始化的其他名称。
关于Graph* g
和Graph g
:有一个至关重要的区别
对象的生命周期(或Graph* g
的生命周期)
指向对象)。
问题3:Graph& g
与运营商&
没有任何关系;它
是一种告诉编译器g
是引用的方法。一个参考
从根本上说,它只是初始化对象的另一个名称(或者
只有名称,如果初始化对象没有其他名称)。
参考文献主要(但不仅限于)用作函数参数。