【问题标题】:C++ Object referencing in different scopes不同范围内的 C++ 对象引用
【发布时间】:2018-12-12 01:01:02
【问题描述】:

我有一个 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;

     }

在我的 Unit 类中,我包含 Rect 类并创建我的单位,在同一个函数中绘制它们。 unit 中还有另一个函数,它通过检查另一个类中发生变化的另一个值来移动 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()中,如何引用Unit::createUnit()中初始化的对象Rect"unit1"和Rect"unit2" >?

当我尝试编译时,它说 unit1 和 unit2 未定义。

【问题讨论】:

  • unit1unit2 是局部变量。它们不存在于它们包含的 { } 块之外。
  • 那些是局部变量。一旦超出范围,它们就会消失。您需要创建范围更广的变量,可能是类成员变量。

标签: c++ object sdl


【解决方案1】:

你不能做你想做的事。非static 局部变量绑定到它们的scope。它们仅在内部可见,并在程序退出由{} 大括号包围的区域时被销毁。

最简单的解决方案是走向完全不同的方向。添加到Unit 一个private 变量以包含Rect,例如,

Rect sprite;

然后替换

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

使用Unit 构造函数

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

并实现类似的构造函数

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

}

冒号:Member Initializer List 开头,而疯狂的?: 是一个名为Ternary or Conditional Operator 的单行if 语句

注意:我不知道unitImageWidthunitImageSizeHeight 是什么,也不知道它们来自哪里。确保你这样做并确保它们是可访问的。

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)

【讨论】:

  • 谢谢。我会尝试实现它。
【解决方案2】:

只需在你的 Unit 类中添加两个 Rect 成员,然后你就可以在不同的成员函数中使用它。
更好地使用指针,如下:

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;
};

【讨论】:

  • 我也会尝试在我使用 Rect 的其他地方实现这一点。谢谢。
  • @SebiStJohnston 在应用此方法时熟悉并利用The Rule of Three
猜你喜欢
  • 2017-06-05
  • 2012-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-05
  • 1970-01-01
  • 2011-04-25
  • 2010-10-11
相关资源
最近更新 更多