c++ - 无法成功创建唯一对象的 std::list

标签 c++ class opengl pointers linked-list

我有一个基于 OpenGL GLUT(是的,我知道,GLUT 很古老)的 C++ 程序,它交替打印出一个蓝色矩形和一个红色正方形,位于 GLUT 窗口中用户单击鼠标的位置。这工作正常。

然而,当我试图修改上述程序以使上述形状在初始动画后保留在 Canvas 上时,我遇到了令人难以置信的麻烦。

我创建了一个 Shape 类,它包含顶点数、颜色、坐标等信息。当程序一次只绘制一个形状时,该类似乎功能齐全。

为了解决一次多个形状的问题,我创建了一个 std::list<Shape>链表。但是,当我通过 std::list<Shape>::iterator 遍历链表时机制,对象似乎在内存中捆绑在一起。也就是说,对于链表中的每个索引,迭代都会产生完全相同的形状对象、坐标和所有内容。

我尝试了以下解决方案:

使链表成为std::list<Shape*>而不是 std::list<Shape> ,

  • 通过Shape* my_shape = new Shape(params)利用堆分配对象,
  • 并结合上述两种方法。

这是我的 void display() GLUT 函数,以及相关的全局变量和类定义/声明:

class Shape
{

public:
    Shape();
    Shape(int, double[], int[]);
    int type; //0 = rectangle, 1 = circle, 2 = triangle
    int numVertices; //stores total number of vertices in the 2D object.
    double* vertexArray; //a dynamic array that stores each vertex's (x, y)-coordinates in alternating successive indices
    int* rgb; //an array that contains the 3 rgb values s.t. rgb = {r, g, b}
    double* center; //an array that contains the (x, y)-coordinates of the shape's center on the 2d plane.
    int velocity[2]; //a array of size 2 that holds the object's x-velocity in index 0 and the object's y-velocity in index 1

};

    //default Shape constructor
Shape::Shape()
{

}

//Shape constructor 
Shape::Shape(int shapeType, double vertices[], int color[]) //constructor for creating a stationary 2D shape
{
    type = shapeType;

    if (shapeType!=1) //as long as shape is NOT a circle, interpret the second constructor parameter as a list of vertices 
    {
        vertexArray = vertices;
    }

    rgb = color;

    if (shapeType==0) //shape is a rectangle
    {
        numVertices = 4;
    }
    else if(shapeType==1) //shape is a circle
    {
        //shape is a circle, therefore the second array param is in fact an array of size 2 containing the (x, y)-coordinates of the circle origin...
        center = vertices;
    }
    else if (shapeType==2) //shape is a triangle
    {
        numVertices = 3; 
    }
}


std::list<Shape> shapeList;
void my_display(void) 
{
  /* clear the buffer */
  glClear(GL_COLOR_BUFFER_BIT);


  //altFlag is just a value to allow alternating between rectangles/circles being printed

  if (altFlag==1)
  {
      printf("Drawing rectangle at: (%g, %g)\n", my_x, my_y);

      /*instantiate a Shape() object representing a blue rectangle*/
      int rgbColor[3] = {0, 0, 1};

      double vertices[4] = {my_x/window_w, my_y/window_h, my_x/window_w + my_rect_w, my_y/window_h + my_rect_h};

      Shape my_rectangle(0, vertices, rgbColor); //uses constructor (shape type, list of vertex coordinates, length of coordinate list, color)

      glColor3f((GLfloat)my_rectangle.rgb[0], (GLfloat)my_rectangle.rgb[1], (GLfloat)my_rectangle.rgb[2]) ; /* (Red, Green, Blue); so here we ask for Blue */
      glRectf(my_rectangle.vertexArray[0], my_rectangle.vertexArray[1], my_rectangle.vertexArray[2], my_rectangle.vertexArray[3]); //call to function to draw a rectangle
      altFlag=0;

      shapeList.push_front(my_rectangle);
  }
  else
  {
      /*instantiate a Shape() object representing a red circle*/
      int circleColor[3] = {1, 0, 0};
      double circleCenter[2] = {(my_x), (my_y)}; //{center x coord, center y coord}
      //Shape* my_circle = new Shape(1, circleCenter, circleColor); 
      Shape my_circle(1, circleCenter, circleColor);

      glColor3f(my_circle.rgb[0], my_circle.rgb[1], my_circle.rgb[2]);
      glCirclef(my_circle.center[0], my_circle.center[1]); //call to function to draw pseudocircle

      altFlag=1;

      shapeList.push_front(my_circle);
  }

  //iterate over shapeList, print out values of the rgb array.
  for (std::list<Shape>::iterator iter = shapeList.begin(); iter != shapeList.end(); iter++)
  {
      printf("%d, %d, %d\n", iter->rgb[0], iter->rgb[1], iter->rgb[2]);
  }

  glutSwapBuffers();

  return;

虽然这是作业的一部分,但问题与所使用的语言有关,而不是类(class)重点的图形库。

最佳答案

Shape 的参数化构造函数这样做:

vertexArray = vertices;

在哪里vertices是声明为 double vertices[] 的函数参数.这是 double *vertices 的语法糖,即,您正在复制一个指针(因为数组在传递给函数时会退化为指针)。

vertexArray被定义为类内部的指针。您甚至提到它是一个“动态数组”,但随后您使用在堆栈上分配的数组( display() 中的局部变量)对其进行了初始化。这使得指针悬空。

你必须制作 vertexArray一个数组并复制数据,而不仅仅是指针。像这样:

class Shape
{
  // ...
  double vertexArray[4];
  // ...
};

Shape::Shape(int shapeType, double vertices[], int color[])
{
    type = shapeType;

    if (shapeType==0) //shape is a rectangle
    {
        numVertices = 4;
    }
    else if(shapeType==1) //shape is a circle
    {
        //shape is a circle, therefore the second array param is in fact an array of size 2 containing the (x, y)-coordinates of the circle origin...
        center = vertices;
    }
    else if (shapeType==2) //shape is a triangle
    {
        numVertices = 3; 
    }

    if (shapeType!=1) //as long as shape is NOT a circle, interpret the second constructor parameter as a list of vertices 
    {
        std::copy(vertices, vertices + numVertices, vertexArray);
    }
}

类推color当然还有。

额外建议

当然,这段代码使用std::vector会好得多或类似的东西而不是普通数组,使用和 enum而不是 int对于 shapeType等。我建议你拿起一个 good C++ book .

关于c++ - 无法成功创建唯一对象的 std::list,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18509995/

相关文章:

C++ 标准库在 .mm 文件中找到,但在 .h 中找不到(Xcode 4.5 LLVM GCC 4.2)

c++ - 向单链表添加值

C++错误: no matching function for call to 'Track::Track(char, char)'

c++ - 我是否需要通过我的几何着色器将颜色传递给片段着色器?

java - 带显示列表的 OpenGL 光照

c++ - 可以通过其他获取操作获取负载重新排序吗? cppreference 说只有非原子的和宽松的通过 acquire 排序

c++ - C++ 中的命名空间别名

python - 当我不能使用 self 时如何上课 - Python

c++将对象存储到该对象的构造函数中的对象数组中

c++ - OpenGL渲染优化