Неправильное использование класса в C ++? - PullRequest
1 голос
/ 27 сентября 2010

Привет, я пытаюсь передать некоторые значения классу, но он не дает мне сказать, что это говорит о недопустимом использовании класса 'Figure', я пытаюсь отправить 3 значения x, y, z, и это все, но это не даст мне, вот что я пытаюсь делать ...

здесь main.cpp и функция, которая вызывает класс. Figure

 for (j = 0; j < num_elems; j++) {
    /* grab and element from the file */
    vlist[j] = (Vertex *) malloc (sizeof (Vertex));
    ply_get_element (ply, (void *) vlist[j]);


    int vert=sprintf(szFile,"vertex: %g %g %g", vlist[j]->x, vlist[j]->y, vlist[j]->z);
    /* print out vertex x,y,z for debugging */
    TextOut(hDC,600,j*20,szFile,vert);
   DrawFig->Figure(vlist[j]->x, vlist[j]->y, vlist[j]->z);
  }

Ошибка здесь

   DrawFig->Figure(vlist[j]->x, vlist[j]->y, vlist[j]->z);
  }

Вот WM_CREATE: где я инициализирую все

case WM_CREATE:
        hDC = GetDC(hWnd);
     //ShowWindow(g_hwndDlg,SW_SHOW);
    hRC=wglCreateContext(hDC);
    wglMakeCurrent(hDC,hRC);
     g_hwndDlg = CreateDialog(hInst,MAKEINTRESOURCE(IDD_DIALOG1),hWnd,DialogProc);

    DrawFig= new Figure(1.0,1.0,1.0);
    initGL();
     break;

вот рисунок.

class Figure
{
    public:
        Figure(float x,float y,float z);
        void Draw();
        float paramx(){
        return x1;
        }
        float paramy(){
        return y1;
        }
        float paramz(){
        return z1;
        }
    protected:
    private:
    float x1,y1,z1;
    list <Figure> m_vertices;
};

и вот рисунок.cpp

Figure::Figure(float x,float y,float z){
    this->x1=x;
this->y1=y;
this->z1=z;
m_vertices.push_back(Figure(x1, y1, z1));
}

void Figure::Draw()
{
    list<Figure>::iterator p = m_vertices.begin();
 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glLoadIdentity();
    gluLookAt(0.0,0.0,4.0,0.0,0.0,0.0,0.0,1.0,0.0);

    glColor3f(0.7f,1.0f,0.3f);
    glBegin(GL_LINE_LOOP);
    while(p != m_vertices.end()){
        glNormal3f(p->paramx(),p->paramy(),p->paramz());
        glVertex3f(p->paramx(),p->paramy(),p->paramz());
        p++;
    }
    glEnd();
}

есть идеи? это opengl, c ++ и я использую кодовые блоки 10.05 на всякий случай о да, я инициализирую его в main.h как этот DrawFig * Figure;

Ответы [ 4 ]

3 голосов
/ 27 сентября 2010

@ dark_charlie ответ почти правильный. Вот лучшая версия, которая на самом деле будет работать, но все же, вероятно, не то, что вы хотите:

class Figure  {
  // ...
public:
  void set(float x, float y, float z);
  // ...
};

void Figure::set(float x, float y, float z)
{
  // Your original code from the constructor
  this->x1 = x;
  this->y1 = y;
  this->z1 = z;
}

Figure::Figure(float x, float y, float z)
{
  // In the constructor call the newly created set function
  set(x, y, z);
  m_vertices.push_back(Figure(x1, y1, z1));
}


// Replace the faulty line with this:
DrawFig->set(vlist[j]->x, vlist[j]->y, vlist[j]->z);

Теперь это почти наверняка не то, что вы хотите. Но очень сложно понять, чего ты хочешь. У вас проблема с дизайном. Проблема дизайна в том, что Figure имеет две обязанности. Это и точка в пространстве, и набор точек, описывающих фигуру. Эта путаница с обязанностями ведет ваш класс к тому, чтобы фактически не быть в состоянии заполнить ни одного из них особенно хорошо.

Вам нужно два класса. Вам нужен класс Point и класс Figure. Класс Figure должен позволять вам определять местоположение фигуры, а также добавлять точки к контуру фигуры.

Огромная подсказка, что что-то не так, это list<Figure> m_vertices;. Очень редко класс концептуально содержит экземпляры самого себя. И обычно, когда вы делаете это, вы создаете свою собственную структуру данных, например дерево или список, а затем класс содержит указатели на свои экземпляры.

Кроме того, тот факт, что простое исправление @ dark_charlie привело к бесконечной рекурсии, является еще одним огромным признаком того, что что-то не так.

Я предполагаю, что это домашнее задание, так что это вся помощь, которую я дам вам, кроме того, что я думаю, что у вас уже есть класс Point, который вы называете Vertex.

2 голосов
/ 27 сентября 2010

Просто о прямом вызове конструктора:

Используйте это вместо:

// destruct and reconstruct
DrawFig -> ~Figure();
new (DrawFig) Figure(vlist[j]->x, vlist[j]->y, vlist[j]->z);

Что он делает:

  1. Вызывает деструктор.

    Сам деструктор вызовет деструктор всех переменных-членов. float s не нуждается / имеет деструктор, но std::list имеет. Деструктор std::list s освободит все содержащие объекты.

  2. Вызывает конструктор.

    Сам конструктор будет вызывать конструктор всех переменных-членов. Опять же, у float этого нет, и они не инициализируются определенным образом, то есть они снова игнорируются. Затем вызывается конструктор std::list, который инициализирует list.

Однако использование решения dark_charlie может быть более чистым.


Мало того, что решение DCs более чистое, оно также делает что-то другое. При повторном вызове конструктора вы также сбросите Figure::m_vertices, и я думаю, что это, вероятно, не то, что вам нужно.

Однако, возможно, вместо set (как в решении DC) вы должны назвать его add или около того.

Также я не уверен, действительно ли вы хотите иметь Figure или Figure::m_vertices таким образом (каждый Figure содержит список других Figure с).

2 голосов
/ 27 сентября 2010

Вы не можете вызвать конструктор напрямую, как пытаетесь. Создайте функцию set (), которая будет выполнять ту же работу, и используйте ее вместо конструктора:

class Figure  {
  // ...
public:
  void set(float x, float y, float z);
  // ...
};

void Figure::set(float x, float y, float z)
{
  // Your original code from the constructor
  this->x1 = x;
  this->y1 = y;
  this->z1 = z;
  // m_vertices.push_back(Figure(x1, y1, z1));
}

Figure::Figure(float x, float y, float z)
{
  // In the constructor call the newly created set function
  set(x, y, z);
}


// Replace the faulty line with this:
DrawFig->set(vlist[j]->x, vlist[j]->y, vlist[j]->z);

РЕДАКТИРОВАТЬ:

Как отмечено в комментариях, у кода есть еще один недостаток - у вас есть список рисунков, который содержится внутри самого рисунка. Я думаю, что вы хотели объявить m_vertices следующим образом:

list <Vertex> m_vertices;

Однако, если вы хотите, чтобы фигура была треугольником (или любым другим многоугольником более высокого порядка), вам нужно будет передать координаты всех трех вершин вместо трех координат одной вершины:

void Figure::set(const Vertex& v1, const Vertex& v2, const Vertex& v3)
{
  m_vertices.push_back(v1);
  m_vertices.push_back(v2);
  m_vertices.push_back(v3);

  // The position of the figure will be its centroid
  this->x1 = (v1.x + v2.x + v3.x) / 3;
  this->y1 = (v1.y + v2.y + v3.y) / 3;
  this->z1 = (v1.z + v2.z + v3.z) / 3;
}

Figure::Figure(const Vertex& v1, const Vertex& v2, const Vertex& v3)
{
  set(v1, v2, v3);
}

Вам также понадобится настроить цикл так, чтобы он читал сразу 3 вершины вместо одной, но я позволю вам это:)

1 голос
/ 27 сентября 2010

Несколько вещей:

  • Вы создали экземпляр класса Figure?
  • Создан ли экземпляр list <Figure> m_vertices;?

Использование функции C malloc с кодом времени выполнения C ++ беспорядочно, лучше всего придерживаться вместо этого добавлен новый для обеспечения согласованности среды выполнения C ++.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...