Troubles with vector of objects?

Alright, I've been working on a version of Battleship and I am having some issues I'm pretty sure with how long some objects are living within a vector.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// TextureLib.h
#pragma once

#include<SFML/Graphics.hpp>
#include<vector>
#include<string>
#include"GTexture.h" // Encapsulated game textures. Encapsulates sf::Texture

class TextureLib
{
private:
	std::vector<GTexture> textureLibrary; // Vector of game texture objects
public:
	TextureLib(void);
	~TextureLib(void);
	void addTexture_toLibrary(const std::string Texture, const std::string name); // These arguements are passed into GTexture constructor
	GTexture getTexture_fromLibrary(const std::string Texture); // Will look through vector textureLibrary for texture with matching name
	bool search(std::string name);
};


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// TextureLib.cpp
#include "TextureLib.h"
#include<iostream>
#include<vector>
#include<SFML/Graphics.hpp>
#include<string>
#include"GTexture.h"

TextureLib::TextureLib(void)
{
	
}


TextureLib::~TextureLib(void)
{
}

void TextureLib::addTexture_toLibrary(const std::string Texture, const std::string name){
	TextureLib::textureLibrary.push_back(GTexture(Texture.c_str(),name.c_str()));
	std::cout << "GTexture " << name << " added to TextureLib with texture loaded from " << Texture << " .";
}

GTexture TextureLib::getTexture_fromLibrary(std::string Texture){
	for(int i = 0; i <= TextureLib::textureLibrary.size(); i++){ 
		if(TextureLib::textureLibrary[i].nameRef == Texture){
			return textureLibrary[i];
		} // i <= size() is needed so we don't go out of bounds within the vector and will always know when to stop looking
		std::cout << "Error: In TextureLib GTexture " << Texture << " could not be found" << std::endl;
	}
}

bool TextureLib::search(std::string name){
	for(int i = 0; i <= TextureLib::textureLibrary.size(); i++){
		if(TextureLib::textureLibrary[i].nameRef == name){
			return true;
		}
	}
	return false;
}


That's my TextureLib class. It's my current of way of having textures stored and accessible. The actual GTexture object here.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// GTexture.h
#pragma once
#include<SFML/Graphics.hpp>
#include<string>
// Encapsulate sf::Texture to have ID reference etc. This is basically purely for organizational purposes
class GTexture
{

public:
	sf::Texture texture; // The actual sf::Texture
	std::string nameRef; // The name reference for when we search for a given texture
	GTexture(const std::string file, const std::string name); // Automatically get the file texture is located in and game texture name
	~GTexture(void);
};

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// GTexture.cpp
#include "GTexture.h"
#include<SFML/Graphics.hpp>
#include<iostream>

GTexture::GTexture(const std::string file, const std::string name) 
{
	GTexture::nameRef.assign(name);
	if(!GTexture::texture.loadFromFile(file.c_str())){
		std::cout << "Error: Could not " << file << " for GTexture " << name " " << std::endl;
	}
}


GTexture::~GTexture(void)
{
	std::cout << "Mr. Destructor Here" << std::endl;
}


The actual object of TextureLib is in my class Game, which is basically the manager of everything. Not a lot done with right now but this is it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//Game.h
#include"TextureLib.h"
#include"SpriteLib.h"
#include<string>
#include<SFML/Graphics.hpp>

class Game
{

public:
	TextureLib GameTextures;
	sf::RenderWindow* window;
	Game();
	~Game(void);
	void Start();
	void StartGame();
	void loadTextures();
};


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// Game.cpp
#include "Game.h"


Game::Game()
{
	Game::window = NULL;
}


Game::~Game(void)
{
}

void Game::Start(){ // Start game, load up resources. Draw up the main menu

}

void Game::StartGame(){ // Start an actual game

}

void Game::loadTextures(){
	Game::GameTextures.addTexture_toLibrary("BattleshipBoard.bmp","board"); // Background for actual game
	Game::GameTextures.addTexture_toLibrary("BattleshipMainMenuBackground.bmp","MainMenuBG"); // Background for main menu only
	Game::GameTextures.addTexture_toLibrary("BattleshipMainMenuButtonExit.bmp","MainMenuExit"); // Exit Button
	Game::GameTextures.addTexture_toLibrary("BattleshipMainMenuButtonPvC.bmp","MainMenuPvC"); // Player vs Computer button
	Game::GameTextures.addTexture_toLibrary("BattleshipMainMenuButtonPvP.bmp","MainMenuPvP"); // Player vs Player button
	Game::GameTextures.addTexture_toLibrary("BattleshipMainMenuTitle.bmp","MainMenuTitle"); // Main Menu title - Not a button
}


Anyways, the console will output when the textures are loaded. I as a test put in the message in the constructor however and it is indeed getting called.

It's really weird how many times it's being called though. I'm sure I'm just doing something frustratingly stupid, but please bear with me I'm a newbie.


Mr. Destructor Here
GTexture MainMenu BG added to TextureLib with texture loaded from BattleshipMainM
enuBackground.bmp .
Mr. Destructor Here
Mr. Destructor Here
Mr. Destructor Here
GTexture MainMenuExit added to TextureLib with texture loaded from BattleshipMai
nMenuButtonExit.bmp .
Mr. Destructor Here
Mr. Destructor Here
Mr. Destructor Here
Mr. Destructor Here
GTexture MainMenuPvC added to TextureLib with texture loaded from BattleshipMain
MenuButtonPvC.bmp .
Mr. Destructor Here
Mr. Destructor Here
Mr. Destructor Here
Mr. Destructor Here
Mr. Destructor Here
GTexture MainMenuPvP added to TextureLib with texture loaded from BattleshipMain
MenuButtonPvP.bmp .
Mr. Destructor Here
GTexture MainMenuTitle added to TextureLib with texture loaded from BattleshipMa
inMenuTitle.bmp .
Mr. Destructor Here


Pretty strange if you ask me. This causing a crash after all of the textures are loaded. I'm absolutely positive it has to do with this code. I'm just not entirely sure why the destructor is being called after the object is added to the vector?
You probably don't want to use a vector for storing textures. Sprites keep a reference to their texture, and vectors will relocate textures when they're resized (often via a push_back.) You might consider using a deque, or a map (with the "name" as the key.)

[Edit: You should avoid making copies of Textures (such as the temporary you create on line 20 of TextureLib.cpp every time you add a Texture to the library) as they're rather expensive hardware resources.]

Last edited on
Ok well as can be seen I use push_back() several times here so that must be the problem. I haven't used maps before but from my understanding they are another STL container and can have its elements directly accessed by the key you mentioned. Rather than having to scan through the whole thing with a for loop (programmer themselves anyways?).

I'll fix the copies issue, this game should take very little resources regardless but good habits must come soon ;)

Last edited on
Topic archived. No new replies allowed.