Ссылка на объект C ++ в разных областях - PullRequest
0 голосов
/ 12 декабря 2018

У меня есть класс Rect такой, что он содержит значения ширины, высоты, x и y фигуры.Класс может рисовать, используя значения в параметре, и перемещать нарисованный прямоугольник.

     Rect::Rect(w, h, x, y, const std::string &image_path) : _w(w), _h(h), 
  _x(x), _y(y)
     {

     SDL_Surface *surface = IMG_Load(image_path.c_str());
     if (!surface) {
     std::cerr << "Failed to create surface.";

     }

    //create texture
    texture = SDL_CreateTextureFromSurface(Window::renderer, surface);
    if (!texture) {
    std::cerr << "Failed to create worker texture.";

     }

     SDL_FreeSurface(surface);

     }

     Rect::~Rect() 
     {
     SDL_DestroyTexture(texture);
     }

     Rect::draw()
     {
       //where the constructor parameters are parsed
       SDL_Rect rect= {_x, _y, _w, _h} ;

       //extra code about some SDL texture stuff and RenderCopy
     }

     Rect::moveX(int x){

     _x +=x;

     }

В своем классе юнитов я включаю класс Rect и создаю свои юниты, рисуя их в той же функции.В модуле есть другая функция, которая перемещает прямоугольник, проверяя другое значение из другого класса, который изменяется.

  Unit::Unit()
  Unit::~Unit()

    void Unit::createUnit(int type, int x, int y){
      if (type == 0)
      {
      Rect unit1(unitImageWidth, unitImageSizeHeight, x, y, "res/unit1.png");

      }
      if (type == 1)
      {
      Rect unit2(unitImageWidth, unitImageSizeHeight, x, y, "res/unit2.png");

      }
    }

   void Unit::moveUnit(int x){
      if(selection == 0)
      {
      unit1.movex(x);
      }

      if (selection ==  1)
      {
      unit2.movex(x);
      }
    }

Мой вопрос:

Когда в Unit :: moveUnit () , как я могу ссылаться на объект Rect "unit1" и Rect "unit2", которые инициализируются в Unit :: createUnit () ?

Когда я пытаюсь скомпилировать, он говорит, что unit1 и unit2 не определены.

Ответы [ 2 ]

0 голосов
/ 12 декабря 2018

Просто добавьте два члена Rect в свой класс Unit, и вы сможете использовать его в различных функциях-членах.
Лучше использовать указатель, как показано ниже:

class Unit
{
 public:
    Unit::Unit()
        : uint1(NULL), uint2(NULL){};
    Unit::~Unit()
    {
        if (uint1 != NULL) {
            delete unit1;
            uint1 = NULL;
        }
        if (uint2 != NULL) {
            delete unit2;
            uint2 = NULL;
        }
    };

    void Unit::createUnit(int type, int x, int y)
    {
        if (type == 0) {
            unit1 = new Rect(unitImageWidth, unitImageSizeHeight, x, y, "res/unit1.png");
        }
        if (type == 1) {
            unit2 = new Rect(unitImageWidth, unitImageSizeHeight, x, y, "res/unit2.png");
        }
    }

    void Unit::moveUnit(int x)
    {
        if (selection == 0) {
            unit1->movex(x);
        }

        if (selection == 1) {
            unit2->movex(x);
        }
    }

 private:
    Rect *unit1;
    Rect *unit2;
};
0 голосов
/ 12 декабря 2018

Вы не можете делать то, что хотите.Не- static локальные переменные связаны с их областью действия .Они видны только внутри и уничтожаются, когда программа выходит из области, ограниченной скобками {}.

Самое простое решение - пойти в совершенно другом направлении.Добавьте к переменной Unit a private, чтобы она содержала Rect, например,

Rect sprite;

Затем замените

void createUnit(int type, int x, int y);

конструктором Unit

void Unit(int type, int x, int y);

И реализовать конструктор, например,

void Unit::Unit(int type, int x, int y): sprite(unitImageWidth, 
                                                unitImageSizeHeight, 
                                                x, 
                                                y, 
                                                type == 0? "res/unit1.png": "res/unit2.png")
{

}

Двоеточие : запускает Список инициализирующих элементов , и этот сумасшедший ?: является одной строкой, если оператор называется Тернарный или условный оператор

Примечание: я не знаю, что такое unitImageWidth и unitImageSizeHeight или откуда они берутся.Убедитесь, что вы делаете и убедитесь, что они доступны.

moveUnit становится

void Unit::moveUnit(int x)
{
    sprite.movex(x);
}

, потому что sprite знает, что это такое и какое изображение было загружено, и может перемещать Rect до x (или что делает movex).

Чтобы использовать вас

Unit myUnit(0, 1024, 42);  // creates a unit of type 0 at coordinates 1024,42
myUnit.movex(88); // moves myUnit to 88,42 (I think)
...