C++ Vector w SFML

0

Czy w poniższym programie gdy tworzymy obiekt statyczny a potem dodajemy go do vector i usuwamy z vector to czy orginalne obiekty nie będą zawalać pamięci RAM?

#include <SFML/Graphics.hpp>
#include <iostream>
#include <vector>
#include "defined.hpp"
#include "console.cpp"
#include "window.cpp"

using namespace std;
class Trash : public sf::CircleShape {
public:
   unsigned int speed = 3+rand()%5;
   bool undestructable = false;
   bool followMouse = false;
   float rot = rand()%21 - 10;
   float x = 0;
   int ncoll = 0;
   sf::Time cooldown = sf::milliseconds(5000+rand()%5000);
   sf::Time start;
   Trash() : sf::CircleShape() { }
   Trash(float r,sf::Clock &clock) {
      this->setRadius(r);
      this->start = clock.getElapsedTime();
      this->setOrigin(r,r);
      this->setOutlineColor(sf::Color(0x000000ff));
      this->setOutlineThickness(2);
   }
   bool isCollision (Trash &target) {

      if (this->getGlobalBounds().intersects(target.getGlobalBounds())) {
            this->ncoll += 1;   target.ncoll += 1;
            this->setOutlineColor(sf::Color(0xff0000ff));
            target.setOutlineColor(sf::Color(0xff0000ff));
            float mx = this->getGlobalBounds().width - abs(abs(this->getGlobalBounds().left)-abs(target.getGlobalBounds().left));
           
            if (this->getPosition().x < target.getPosition().x) {
               this->x = -(float) (this->speed); target.x = target.speed;
               this->move(-mx/2.0,0); target.move(mx/2.0,0);
            }
            else {
               this->x = this->speed; target.x = - (float) (target.speed);
               this->move(mx/2.0,0); target.move(-mx/2.0,0);
            }
            return true;
      }
      return false;
   }
   bool isCollision2(Trash &target) {
      float mr;
      if (  (mr = sqrt(pow(this->getPosition().x-target.getPosition().x,2) + pow(this->getPosition().y-target.getPosition().y,2))) <
      this->getRadius() + target.getRadius() ) {
            this->ncoll += 1;   target.ncoll += 1;
            this->setOutlineColor(sf::Color(min(255,(this->ncoll)*50),0,0,255));
            target.setOutlineColor(sf::Color(min(255,(target.ncoll)*50),0,0,255));
            mr = (this->getRadius() + target.getRadius() - mr)/2.0;
            if (this->getPosition().x < target.getPosition().x) {
               this->x = - (float) (this->speed); target.x = target.speed;
               this->move(-mr,0); target.move(mr,0);
            }
            else {
                this->x = this->speed; target.x = - (float) (target.speed);
               this->move(mr,0); target.move(-mr,0);
            }
            return true;
      }
      return false;
   }

   float xdown() {
      if (this->x==0 || abs(this->x)<0.4) { return this->x = 0; }
      else if (this->x < 0) { this->x += 0.2; return this->x; }
      else if (this->x > 0) { this->x -= 0.2;  return this->x; }
      else return 0;
   }
};




int main() {
   srand(time(NULL)); setlocale(LC_ALL, "");
   startConsole();
   sf::RenderWindow W;
   createMyWindow(W,"Kolizje");
   setSFMLWindow(W.getSystemHandle());

vector <Trash> Rain; 
Rain.reserve(250);
sf::Texture* tex = new sf::Texture;
tex->loadFromFile("flake.png");
   sf::Clock clock;
   sf::Event e;

Trash first(30,clock);
first.setFillColor(sf::Color(0x000000ff));
first.setPosition(SCREENX/2,SCREENY/2);
first.undestructable=true;
first.followMouse=true;
first.speed = 1;

Rain.push_back(first);

   unsigned long long int steps=0;
   while (W.isOpen()) {
         steps++;
      while (W.pollEvent(e)) {
         if (e.type == sf::Event::Closed || (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape) )) W.close();
      }
      W.clear(sf::Color(0xffffffff));
      if (!(steps%3)) {
         Trash n(12,clock);
         n.setTexture(tex);
         n.setPosition(rand()%SCREENX+1,-(rand()%40));
         Rain.push_back(n);
      }
      if (Rain.size())
         for (auto k = Rain.begin(); k!=Rain.end(); k++) 
         {
            
            if (k->followMouse && sf::Mouse::isButtonPressed(sf::Mouse::Left))
               k->move((-k->getPosition().x+sf::Mouse::getPosition().x)/5 , (-k->getPosition().y+sf::Mouse::getPosition().y)/5 );
            else
               k->move(k->xdown(), k->speed);
            k->rotate(k->rot);
            
            for (auto m = Rain.begin(); m!=Rain.end(); m++) 
            {
               if (k==m) continue;
              
               k->isCollision2(*m); 
            }

            W.draw(*k);

          
            if ( !k->undestructable &&
                ((k->ncoll >= 10)  ||  (clock.getElapsedTime().asMilliseconds() - k->start.asMilliseconds() > k->cooldown.asMilliseconds()))  ) {
               Rain.erase(k);
               k--;
            }
         }
      W.display();
   }

   return 0;
}
1

Chyba automatyczny a nie statyczny?
Pytanie fundamentalne: czy coś działa nie dość wydajnie, czy martwisz się na zapas? Bo zasadniczo tak, Trash będzie żyć w wektorze i poza nim.

Jeśli Cię to martwi to zrób move do wektora (o ile typ jest movable), utwórz obiekt wprost w nim przez emplace_back (o ile możesz), stwórz wektor dynamicznie alokowanych obiektów albo wektor reference_wrapperów, ładuj obiekty do wektora z wewnętrznego scope’u... no możliwości jest trochę.

2

Wygląda na pytanie o mikro-optymalizację, czyli na coś co jest bezcelowe/bezsensu, a początkujący często się na tym fiksują.
Jak chcesz coś optymalizować, to zainteresuj się profilerem pojęciem złożoności czasowej/pamięciowej i doczytaj co to jest mikro-optymalizacja i czemu jest zła.

1

Nie musisz tworzyć obiektu i następnie kopiować go do wektora.

  if (!(steps%3)) {
         Rain.emplace_back(12,clock);
         Rain.back().setTexture(tex);
         Rain.back().setPosition(rand()%SCREENX+1,-(rand()%40));
      }

P.S. Nigdzie nie usuwasz tekstury tex.

1 użytkowników online, w tym zalogowanych: 0, gości: 1