C++/迭代器如何为一组 class 对象工作?

C++ / How does a iterator work for a Set of class object?

我一直在自学 C++,发现了一件有趣的事情。

根据this web page,

The most obvious form of iterator is a pointer.

所以,我曾经认为迭代器对象的工作方式几乎与指针相同(例如int *i);

不过,现在我想说迭代器对象更像是指针的指针(例如int **i)而不是指针(int *i)会更准确。

我在编写以下代码时注意到了这一点。

set<Point*, Point> points; //This class encapsulates x and y coordinates for a 2 dimensional point
set<Point*, Point>::iterator it;

int x = 22;
int y = 4;
Point* pt = new Point(x, y);
points.insert(pt);
//Similar statements are here, to insert other Point objects with different arguments

for (it = points.begin(); it != points.end(); it++) {
    cout << "**it: " << **it << ", *it :" << *it << ", Address : " << &it << endl;
}

因此,

  1. **it 显示指针 class 对象的值

  2. *it 显示地址

  3. &it 显示了 it 对象的地址

所以,迭代器对象(it)和**it基本一样,这样说对吗?

另一个与迭代器有点不同的问题:

如果我需要制作一组 class 对象,例如:set<ClassName*, ClassName> SetName;,正确的方法是什么? (只要此 class 包含可比较的数据类型,如 intdouble

如果您能提供一些建议,我将不胜感激。

这是一个错误的假设。在您的示例中,集合的 value_type 是指针 Point **it 为您提供集合中的一个元素,该元素是对该 value_type 的某个对象的引用,该对象的类型为 Point *++it "points" 到下一个集合中的元素。所以迭代器的行为方式与指向 value_type.

的对象的指针相同

当您使用像 **it 这样的表达式时,第二个取消引用不会应用于迭代器。它应用于集合中的对象。你可以用下面的方式想象表达式 **it

Point *pp = *it;

Point p = *pp;

容器的迭代器负责为您提供对容器元素的访问。因此,如果容器中的元素具有 value_type 类型,则迭代器提供对此 value_type 的这些元素的访问。元素又可以是指向对象的指针,甚至可以是指向对象的指针等等。

至于你的第二个问题,那么如果 class 有相应的运算符函数并且 class 本身有一些简单的默认构造函数那么你可以使用这种方法,尽管最好定义一个单独的比较器或简单地为 class 的对象定义 operator <。在最后一种情况下你可以写

std::set<Point> s;

没有明确的第二个模板参数。

这是您的方法的演示程序

#include <iostream>
#include <set>



int main() 
{
    struct Point
    {
        int x, y;
        bool operator ()( const Point &p1, const Point &p2 ) const
        {
            return p1.x < p2.x && p1.y < p2.y;
        }
    };

    std::set<Point, Point> s;
    s.insert( { 2, 2 } );
    s.insert( { 1, 1 } );

    for ( const Point &p : s ) std::cout << p.x << ' ' << p.y << std::endl;

    return 0;
}

程序输出为

1 1
2 2