我将整个代码放在github上:https://github.com/marianatuma/CG
我有一个名为point的结构,在line.h
中声明,以及一个有两个点的开始和结束的类。编辑:我以前没有添加它,但Line继承自GraphObj。 graphObj.h
:
class GraphObj {
private:
type t;
std::string name;
public:
GraphObj(type t, std::string name);
type getType();
std::string getName();
};
line.h
:
#ifndef LINE_H
#define LINE_H
struct point {
double x;
double y;
};
class Line {
private:
point start;
point end;
public:
Line(type t, std::string name) : GraphObj(t, name) {};
void setStart(double x, double y);
void setEnd(double x, double y);
point getStart();
point getEnd();
};
#endif
line.cpp
:
#include "line.h"
void Line::setStart(double x, double y) {
this->start.x = x;
this->start.y = y;
}
void Line::setEnd(double x, double y) {
this->end.x = x;
this->end.y = y;
}
point Line::getStart() {
return start;
}
point Line::getEnd() {
return end;
}
当我尝试访问这些点时,我总是遇到分段错误。我试着让它们公开,没有用。我也试过使用吸气剂,它也没有用。以下是我如何初始化它们:
该行位于一个行列表中,称为显示文件,它将与cairo一起用于绘制它们。
displayFile.h
:
#ifndef DISPLAYFILE_H
#define DISPLAYFILE_H
#include <list>
#include "graphObj.h"
class DisplayFile {
private:
std::list<GraphObj*>* objectList;
std::list<GraphObj*>::iterator it;
int size;
public:
DisplayFile();
void add(GraphObj* g);
GraphObj* getNextObject();
void resetIterator();
int getSize();
};
#endif
displayFile.cpp
:
#include "displayFile.h"
DisplayFile::DisplayFile() {
this->objectList = new std::list<GraphObj*>();
this->it = objectList->begin();
this->size = 0;
}
void DisplayFile::add(GraphObj* g) {
std::list<GraphObj*>::iterator tempIt;
tempIt = objectList->begin();
this->objectList->insert(tempIt, g);
this->size++;
}
GraphObj* DisplayFile::getNextObject() {
return *++it;
}
void DisplayFile::resetIterator() {
it = objectList->begin();
}
int DisplayFile::getSize() {
return size;
}
DisplayFile返回一个GraphObj而不是objectList,所以它必须自己迭代objectList,因此是resetIterator(所以当主代码完成遍历列表时,它会将迭代器重置为列表的开头,但我和到目前为止,我没有在任何地方调用此方法。 main.cpp
中使用Line实例的代码如下:
static void do_drawing(cairo_t *cr)
{
/* not using these right now
cairo_set_source_rgb(cr, 0, 0, 0);
cairo_set_line_width(cr, 0.5);
*/
int size = df->getSize(); //df is the list
for(int i = 0; i < size; i++) {
Line* g = df->getNextObject();
point start = g->getStart();
}
}
问题仅在我尝试访问点时开始,我可以从该行实例访问其他属性而不会出现问题。我做错了什么?
编辑:我希望我提供了足够的信息,主要代码很长,并且与线路课程没什么关系,所以我不认为它是这样的相关的。
答案 0 :(得分:4)
问题在于您的列表类。
class DisplayFile {
private:
std::list<GraphObj*>* objectList; // Why not just a list<GraphObj*>
std::list<GraphObj*>::iterator it; // Why use this?
int size; // WHY manually keep track of a STL container size?
public:
DisplayFile();
void add(GraphObj* g);
void resetIterator();
int getSize();
};
在您的实施文件中:
GraphObj* DisplayFile::getNextObject() {
return *++it;
}
正如我已经评论过的那样:这是胜利者......想一想,如果it
已经恰好是列表中的最后一个元素,那么你问getNextObject()
?的 动臂 强>
我不明白为什么你不能用一个漂亮而简单的DisplayFile
取代整个std::list
课程:
std::list<GraphObj*> objectList;
// I would also advice to change to smart pointers here
// for example: std::list<std::shared_ptr<GraphObj> > objectList;
// or std::list<std::unique_ptr<GraphObj> > objectList;
然后你只需使用STL方法来处理列表:
在前面添加一个项目: (为了简单起见,我们假设GraphObj
有一个默认构造函数)
GraphObj* g = new GraphObj();
objectList.push_front(g);
// If you change to smart pointers:
// objectList.push_front(std::make_shared<GraphObj>());
// or
// objectList.push_front(std::make_unique<GraphObj>());
获取列表大小:
objectList.size();
遍历列表:
for (std::list<GraphObj*>::const_iterator it = objectList.begin();
it != objectList.end();
++it)
{
point start = (*it)->getStart();
// or whatever you need to do here
}
或者更好的范围:
for (const auto & graphObj : objectList)
{
point start = graphObj->getStart();
// or whatever you need to do here
}
答案 1 :(得分:1)
问题可能来自你的getStart和getEnd,因为它们会返回一个点,这将创建你的起点或终点的副本(我认为),即不使用行中的点而是副本。这通常不是什么大不了的事情,但是如果你想改变一个x或y值并且让新值增加,你需要引用原始点x和y值。 试试这个,改变
point getStart();
point getEnd();
到
point *getStart() { return &start; }
point *getEnd() { return &end; }
并在你的do_drawing(cairo_t * cr)更改
point start = g->getStart();
到
point *start = g->getStart();
start->x = value; // or
double value = start->x; // or however you want to use start
答案 2 :(得分:1)
因为你没有初步化结构。
稍微改变一下构造函数
从此
Line(type t, std::string name) : GraphObj(t, name) {};
到
Line(type t, std::string name) : GraphObj(t, name) , start(),end() {};
这可能有所帮助。