0

I am trying to create a program that has the user click twice on the screen and a rectangle is drawn according to what was clicked.

Right now all I am trying to do is set my classes up to be able to correctly draw a rectangle manually without worrying about where the user clicks.

Eventually my program will be able to draw stuff like circles and triangles so I decided to use Polymorphism and have each shape type (i.e. Rectangle) be its own class that inherits from a class called Shapes.

I then have a class called Game which holds a Shapes object.

Shapes.h

#ifndef _shapes_h_
#define _shapes_h_
#include <vector>
#include "glut.h"

class Shapes
{
public:
    void DrawAll() const;
    void Add(Shapes * shape);
    virtual void Draw() const {}

protected:   
    std::vector<Shapes *> mShapes;
};

#endif  

Shapes.cpp

#include "Shapes.h"
#include <iostream>

void Shapes::DrawAll() const
{
    int i;
    for (i = 0; i < mShapes.size(); i++)
    {
        mShapes[i]->Draw();
    }
}

void Shapes::Add(Shapes * shape)
{
    mShapes.push_back(shape);
}

Rectangle.h

#ifndef _rectangle_h_
#define _rectangle_h_
#include "Shapes.h"

class Rectangle : public Shapes
{
public:
    Rectangle(std::vector<int> p1, std::vector<int> p2);
    void Draw() const;

private:
    std::vector<int> mP1;
    std::vector<int> mP2;
};

#endif

Rectangle.cpp

#include "Rectangle.h"
#include <iostream>

Rectangle::Rectangle(std::vector<int> p1, std::vector<int> p2)
{
    mP1 = p1;
    mP2 = p2;
}


void Rectangle::Draw() const
{
    std::cout << "Draw Me " << std::endl;
    glColor3d(0, 0, 0);

    glBegin(GL_QUADS);
    glVertex2d(mP1[0], mP1[1]);
    glVertex2d(mP2[0], mP1[1]);
    glVertex2d(mP2[0], mP2[1]);
    glVertex2d(mP1[0], mP2[1]);
    glEnd();
}

Game.h

#ifndef _game_h_
#define _game_h_

#include <vector>
#include "Shapes.h"

class Game
{
public:
    void Click(int x, int y);
    void Draw();

private:    
    Shapes mTest;
};

#endif

The first Game.cpp below is coded in a way of what I am trying to do, but it throws me the error Unhandled exception at 0x001AF742 in Shapes.exe: 0xC0000005: Access violation reading location 0x00000001. After looking into this, I've found that some __vfptr hidden pointer variable (that I think controls virtual stuff) gets set to 0 and causes memory issues.

Note, Click() only gets called when the mouse is pressed, Draw() is called anytime any type of event happens (e.i. mouse press, mouse release, key press, key release etc.) When the mouse is pressed, both events get called, but Click() gets called first.

Also, mTestis the variable that is the Shapes object.

Game.cpp: Doesn't Work

#include "Game.h"
#include "Rectangle.h"
#include <iostream>

void Game::Click(int x, int y)
{     
    std::vector<int> p1;
    p1.push_back(200);
    p1.push_back(200);

    std::vector<int> p2;
    p2.push_back(250);
    p2.push_back(250);

    Rectangle rect(rp1, rp2);

    Shapes * rectangle = &rect;
    mTest.Add(rectangle);
}

void Game::Draw()
{       
    mTest.DrawAll();
}

However, what seems to baffle me is if I add a Shape Rectangle to mTest inside of the Draw() function right before I call DrawAll(), it works. However, I want to be able to create the Rectangle depending on where the User clicks, and this method wont allow that.

Game.cpp: Works

#include "Game.h"
#include "Rectangle.h"
#include <iostream>

void Game::Click(int x, int y)
{     
}

void Game::Draw()
{
    std::vector<int> p1;
    p1.push_back(200);
    p1.push_back(200);

    std::vector<int> p2;
    p2.push_back(250);
    p2.push_back(250);

    Rectangle rect(rp1, rp2);

    Shapes * rectangle = &rect;
    mTest.Add(rectangle);
    mTest.DrawAll();
}
4

1 回答 1

1

在 Shapes 类中替换

std::vector<Shapes *> mShapes; 

经过

std::vector<std::shared_pointer<Shapes>> mShapes; 

比替换代码

Rectangle rect(rp1, rp2);

Shapes * rectangle = &rect;
mTest.Add(rectangle);

经过

mTest.Add(std::make_shared<Rectangle>(rp1, rp2));

最后替换方法定义

void Shapes::Add(Shapes * shape)

经过

void Shapes::Add(std::shared_ptr<Shapes> shape)

它使您的代码有效。

摘要:如果您需要指针,请考虑智能指针(@user657267 提到的 std::unique_ptr 也是智能指针)。您可以在此处此处的许多地方阅读有关智能指针的信息。为了更好的设计,不要忘记设计模式。

于 2015-04-11T23:59:27.923 回答