c++ 满足条件后,删除类自身内部的类示例化

nx7onnlm  于 2023-01-15  发布在  其他
关注(0)|答案(1)|浏览(119)

我正在Arduino的16x2液晶显示器上制作一个无限跑步者游戏。
敌人在屏幕上向左爬行,当他们到达末尾时,我想删除敌人类的示例,但我不知道怎么做,我想让它在x位置为零时,在update函数中删除自己。
这里是我的代码:
课程:

class Enemy {
private:
  int xPos, yPos;
public:
  Enemy::Enemy(int xPos, int yPos) {
    this->xPos = xPos;
    this->yPos = yPos;
  }

  draw() {
    lcd.setCursor(xPos, yPos);
    lcd.print("E");
  }

  move() {
    //erase enemy at last position
    lcd.setCursor(xPos, yPos);
    lcd.print(" ");
    //move enemy
    xPos--;
    if(xPos == 0){
      delete(this);
    }
  }
};

剩下的就是

#include <LiquidCrystal.h>

// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
const int rs = 7, en = 8, d4 = 9, d5 = 10, d6 = 11, d7 = 12, buttonPin = 2;
LiquidCrystal lcd = LiquidCrystal(rs, en, d4, d5, d6, d7);
unsigned int playerYPos = 1, buttonPrevious;
const long playerUpdateInterval = 32, enemyMoveInterval = 500;
unsigned long lastUpdatedPlayerMillis = 0, lastMovedEnemiesMillis;


class Enemy {
private:
  int xPos, yPos;
public:
  Enemy::Enemy(int xPos, int yPos) {
    this->xPos = xPos;
    this->yPos = yPos;
  }

  draw() {
    lcd.setCursor(xPos, yPos);
    lcd.print("E");
  }

  move() {
    //erase enemy at last position
    lcd.setCursor(xPos, yPos);
    lcd.print(" ");
    //move enemy
    xPos--;
    if(xPos == 0){
      delete(this);
    }
  }
};

Enemy e(15, 1);

void drawPlayer() {
  lcd.setCursor(1, playerYPos);
  lcd.print("P");
}


void updatePlayer() {
  uint8_t button = digitalRead(buttonPin);
  //check if button is pressed
  if (button == LOW && buttonPrevious == HIGH) {
    //erase player at last position
    lcd.setCursor(1, playerYPos);
    lcd.print(" ");
    //move player
    playerYPos = 1 - playerYPos;
  }
  buttonPrevious = digitalRead(buttonPin);
}

void setup() {
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  //initialize the pushbutton pin
  pinMode(buttonPin, INPUT_PULLUP);
  buttonPrevious = digitalRead(buttonPin);
  Serial.begin(9600);
}

void loop() {

  unsigned long currentMillis = millis();
  //update player 30 times a second
  if (currentMillis - lastUpdatedPlayerMillis >= playerUpdateInterval) {
    //reset counter since last updated
    lastUpdatedPlayerMillis = currentMillis;
    updatePlayer();
  };
  //move enemies ??? times a second
  if(currentMillis - lastMovedEnemiesMillis >= enemyMoveInterval) {
    lastMovedEnemiesMillis = currentMillis;
    e.move();
  }
  drawPlayer();
  e.draw();
}

我试过使用delete()函数,并在google上查找"如何删除类或对象自身的示例"。
目前,它的行为刚刚好,直到其x的位置击中zero,然后它拒绝删除自己,尽管xPos的值是负的,敌人有点小故障,在屏幕上向左走,但重新产卵半随机在显示器的中间。

ttcibm8c

ttcibm8c1#

从一个类的方法中调用它的析构函数不是一个好主意。delete()将调用类释放器和is meant to destroy a class instance that was created using the new expression。一般来说,你不知道这个类示例是如何创建的;它可能已经被分配到堆栈上,在这种情况下,结果是不可预测的。
在您的示例中,示例化类的全局示例,但不能使用delete释放该示例。
对您的代码的一些建议:

  • 保持一个指向类示例的全局指针。2用你的setup()生成类示例并使用指针跟踪它,用loop()在需要的时候删除示例(并可能重新生成新的示例)。
  • Enemy类中,维护一个可以通过方法从loop()使用的状态,这样就可以确定类示例何时可以删除。
  • 在实现指针时,检查Arduino SDK是否支持std::unique_ptr,这样可以减少对原始new/delete指令的需求。

希望这能帮上忙,

相关问题