刚开始用C ++编程。
我创建了一个Point类,一个std :: list和一个像这样的迭代器:
class Point {
public:
int x, y;
Point(int x1, int y1)
{
x = x1;
y = y1;
}
};
std::list <Point> pointList;
std::list <Point>::iterator iter;
然后我将新点推到pointList。
现在,我需要遍历pointList中的所有点,所以我需要使用迭代器进行循环。这是我搞砸的地方。
for(iter = pointList.begin(); iter != pointList.end(); iter++)
{
Point currentPoint = *iter;
glVertex2i(currentPoint.x, currentPoint.y);
}
击> <击> 撞击>
你们是对的,问题不在我的迭代列表中。看来问题是当我试图将某些内容推到列表中时。
确切错误:
mouse.cpp:在函数
void mouseHandler(int, int, int, int)': mouse.cpp:59: error: conversion from
Point *'到非标量类型`Point'请求
这些行是:
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
Point currentPoint = new Point(x, y);
pointList.push_front(currentPoint);
}
Point *与非标量类型Point之间的转换是什么?我只是想创建新的点并将它们推到列表中。
答案 0 :(得分:2)
一些事情..
iter->x
和iter->y
而不是复制值?编辑:
根据OP中的新信息。您正在尝试新建一个非指针对象,然后尝试将该点填充到只接受对象的向量中。你要么必须使向量成为指针的向量,要么记住在词后删除它们或在堆栈上创建新点并将它们复制到带有标准赋值的向量中。试试这个:
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
Point currentPoint = Point(x, y);
pointList.push_front(currentPoint);
}
答案 1 :(得分:2)
那应该是有效的代码。
#include <iostream>
#include <list>
class Point {
public:
int x, y;
Point(int x1, int y1)
{
x = x1;
y = y1;
}
};
int main()
{
std::list<Point> points;
points.push_back(Point(0, 0));
points.push_back(Point(1, 1));
points.push_back(Point(2, 2));
std::list<Point>::iterator iter;
for(iter = points.begin(); iter != points.end(); ++iter)
{
Point test = *iter;
std::cout << test.x << ", " << test.y << "; ";
}
std::cout << std::endl;
return 0;
}
使用此代码:
jasons-macbook41:~ g++ test.cpp
jasons-macbook41:~ ./a.out
0, 0; 1, 1; 2, 2;
jasons-macbook41:~
虽然我不会像你的代码那样创建Point的临时副本。我会像这样重写循环:
for(iter = points.begin(); iter != points.end(); ++iter)
{
std::cout << iter->x << ", " << iter->y << "; ";
}
迭代器在语法上类似于指针。
编辑: 鉴于您的新问题,请从构造线中删除“新”。这是创建指向Point的指针,而不是堆栈上的Point。这是有效的:
Point* temp = new Point(0, 0);
或者这个:
Point temp = Point(0, 0);
你最好还是后者。
答案 2 :(得分:1)
如果您已经有一个想要应用于整个列表的函数,那么std :: for_each就是要走的路,例如,
std::for_each(pointList.begin(), pointList.end(), myGreatFunction);
如果你必须编写for循环,那么就像这样:
std::list<Point>::iterator itEnd = pointList.end();
for(std::list<Point>::iterator itCur=pointList.begin(); itCur != itEnd; ++itCur) {
yourFunction(itCur->x, itCur->y);
}
注意:
答案 3 :(得分:1)
非标量问题是因为您将Point指针(operator new的返回值)分配给Point堆栈对象(因为它不是代码中的Point *)。
我建议说
Point currentPoint(x, y);
pointList.push_front(currentPoint);
请注意,currentPoint将复制到您的列表中; Point的隐式生成的复制构造函数(因为你没有在类中声明一个Point(const Point&amp; other)构造函数,编译器为你做了一个)将currentPoint.x和currentPoint.y复制到列表中;在这种情况下,那没关系。点很小,因此复制费用很低,而且它只包含两个整数,因此可以直接复制整数。
答案 4 :(得分:1)
此答案指的是问题的编辑版本。
正如gbrandt在他的答案的编辑版中所说,你的问题是你正在尝试动态分配Point
的实例,然后将其分配给Point
对象而不是指向 Point
的指针。 new
的结果是指向 Point
的指针,而不是Point
对象 - 在这种情况下您真正想要的是后者,您在没有new
:
Point currentPoint(x, y);
pointList.push_front(currentPoint);
由于list<T>::push_front()
推送了列表中Point
对象的副本,因此您无需在此处进行任何动态分配。在可能的情况下避免动态分配更安全,因为它很容易导致内存泄漏 - 例如以下替代代码(编译和工作)导致内存泄漏,因为currentPoint
指向的对象永远不会delete
d:
Point *currentPoint = new Point(x, y);
pointList.push_front(*currentPoint); // Notice the "*"
当然你可以在末尾添加delete currentPoint;
以消除泄漏,但是为什么在基于堆栈的分配能够更快,更简单地完成工作时使用慢动态分配?
答案 5 :(得分:0)
如果你不想使用std :: foreach ,这就是我通常如何处理这样的循环:
for (iter curr = pointListObject.begin(), end = pointListObject.end(); curr != end; ++curr)
{
glVertex2i(curr->x, curr->y);
}
小心这些要点:
答案 6 :(得分:0)
您是否已将此代码剪切并粘贴到.cpp文件中的SO中,或者您是否重新键入了该代码?从您的错误消息的声音,我猜想原始代码说
glVertex2i(iter.x, iter.y);
正如gbrandt指出的那样,它没有正确地解引用迭代器。
我会按如下方式重写循环:
std::list<Point>::const_iterator iter = pointList.begin();
const std::list<Point>::const_iterator end = pointList.end();
for (; iter != end; ++iter) {
const Point& p = *iter;
glVertex2i(p.x, p.y);
}
主要的变化是使用const_iterators而不是非const,因为你的循环不打算修改列表内容。然后,抓住begin()&amp;的值。 end()恰好一次,使用preincrement,并将迭代器解引用一次到const引用中。这样你就没有复制了,你的原始代码复制了* iter所引用的Point对象,并且你可以避免两次取消引用迭代器,效率和你在这里一样多。
现在,对于一些未经请求的OpenGL建议,我还指出顶点数组可能是比立即模式(glVertex *)调用更好的选择。
希望这会有所帮助......