【问题标题】:Error: taking address of temporary [-fpermissive]错误:获取临时地址 [-fpermissive]
【发布时间】:2013-05-05 02:13:27
【问题描述】:

我已经研究了几个小时,但无济于事。基本上我有

struct rectangle {
    int x, y, w, h;
};

rectangle player::RegionCoordinates() // Region Coord
{
    rectangle temp;
    temp.x = colRegion.x + coordinates.x;
    temp.w = colRegion.w;
    temp.y = colRegion.y + coordinates.y;
    temp.h = colRegion.h;

    return temp;
}

// Collision detect function
bool IsCollision (rectangle * r1, rectangle * r2)
{
    if (r1->x < r2->x + r2->w &&
        r1->x + r1->w > r2->x &&
        r1->y < r2->y + r2->h &&
        r1->y + r1->h > r2->y) 
        {
            return true;
        }
    return false;
}

//blah blah main while loop
if (IsCollision(&player1.RegionCoordinates(), &stick1.RegionCoordinates())) //ERROR
{
    player1.score+=10;
    stick1.x = rand() % 600+1;
    stick1.y = rand() % 400+1;
    play_sample(pickup,128,128,1000,false);
}

有什么想法吗?我敢肯定这是很明显的事情,但对于我的生活,我无法弄清楚。

【问题讨论】:

    标签: c++ collision-detection collision allegro


    【解决方案1】:

    RegionCoordinates() 按值返回对象。这意味着对RegionCoordinates() 的调用将返回rectangle 的临时实例。正如错误所说,您正在尝试获取此临时对象的地址,这在 C++ 中是不合法的。

    为什么IsCollision() 无论如何都要接受指针?通过 const 引用获取其参数会更自然:

    bool IsCollision (const rectangle &r1, const rectangle &r2) {
    if (r1.x < r2.x + r2.w &&
        r1.x + r1.w > r2.x &&
        r1.y < r2.y + r2.h &&
        r1.y + r1.h > r2.y) {
            return true;
        }
            return false;
    }
    //blah blah main while loop
    if (IsCollision(player1.RegionCoordinates(), stick1.RegionCoordinates())) //no error any more
    {
    player1.score+=10;
    stick1.x = rand() % 600+1;
    stick1.y = rand() % 400+1;
    play_sample(pickup,128,128,1000,false);
    }
    

    【讨论】:

      【解决方案2】:

      由于IsCollision 采用rectangle * 并且您在此处获取结果的地址:

      if (IsCollision(&player1.RegionCoordinates(), &stick1.RegionCoordinates()))
      

      您很可能会从RegionCoordinates() 返回一个rectangle,这是一个临时变量,因为它会在if 语句完成后消失。如果您将RegionCoordinates() 的结果分配给一个变量,那么它将不再是临时的,您可以获取它的地址:

      rectangle r1 = player1.RegionCoordinates() ;
      rectangle r2 = stick1.RegionCoordinates() ;
      if (IsCollision(&r1, &r2))
      

      或者,您可以将参数作为 const 引用,这将是更多的 C++ 方式:

      bool IsCollision (const rectangle &r1, const rectangle  &r2)
      

      【讨论】:

      • 是否有关于“如果将 RegionCoordinates() 的结果分配给变量,那么它将不再是临时的”的规范?
      【解决方案3】:

      鉴于您遇到的错误类型,我必须假设RegionCoordinates() 按值返回一个对象,从而导致创建一个临时对象,而您正在获取该临时对象的地址。

      address-of 运算符需要 lvalue 作为其操作数,但您将其应用于 rvalue(临时是 rvalues)。

      您可以这样做(如果您不使用 C++11,请将 auto 替换为 RegionCoordinates 返回的类型):

      auto rcPlayer1 = player1.RegionCoordinates();
      auto rcStick1 = player1.RegionCoordinates();
      if (IsCollision(&rcPlayer1, &rcStick1)) //ERROR
      {
          player1.score+=10;
          stick1.x = rand() % 600+1;
          stick1.y = rand() % 400+1;
          play_sample(pickup,128,128,1000,false);
      }
      

      或者,您可以更改IsCollision,使其接受引用而不是指针as suggested by Angew in his answer

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-09
        • 2021-11-05
        • 1970-01-01
        相关资源
        最近更新 更多