I need to call a method from something that has been stored inside of an std::list. Currently, the loop runs and the print inside prints to the console, but the elements inside the list do not actually print what they are supposed to. Here are the relevant files:
#include "TextWindow.hpp"
#include "TextElement.hpp"
#include <iostream>
TextWindow::TextWindow(const TextureHolder& textures, const FontHolder& fonts, sf::Window& windows, Fonts::ID fontID, sf::String text)
: mSprite(textures.get(Textures::WindowDefault))
, mHitpoints(10)
, mWindow(windows)
{
sf::FloatRect bounds = mSprite.getLocalBounds();
mSprite.setOrigin(bounds.width / 2.f, bounds.height / 2.f);
addElements(text, fonts.get(fontID));
}
void TextWindow::addElements(sf::String text, sf::Font font)
{
TextElement e(text, font, 10, xPos, yPos, 10, 10);
mElements.push_back(e);
}
void TextWindow::drawCurrent(sf::RenderTarget& target, sf::RenderStates states) const
{
target.draw(mSprite, states);
for(std::list<Element>::const_iterator iterator = mElements.begin(); iterator != mElements.end(); ++iterator)
{
//std::cout << "IN TEXTWINDOW PRINT ITERATOR" << std::endl;
(*iterator).drawCurrent(target, states);
}
}
void TextWindow::updateCurrent(sf::Time dt)
{
}
And
#include "TextElement.hpp"
#include <iostream>
TextElement::TextElement(sf::String text, sf::Font font, int textSize, int xOrig, int yOrig, int xPos, int yPos)
: mText(text, font, textSize)
, xpos(xPos)
, ypos(yPos)
{
mText.setOrigin(xOrig, yOrig);
mText.setColor(sf::Color::Green);
}
void TextElement::drawCurrent(sf::RenderTarget& target, sf::RenderStates states) const
{
std::cout << "TEXTELEMENT" << std::endl;
target.draw(mText, states);
}
void TextElement::updateCurrent(sf::Time dt)
{
//Do nothing, text doesn't need to update!
}
Any suggestions?
EDIT: After changing the list to std::unique_ptr, I get the following error:
1>------ Build started: Project: Byte, Configuration: Debug Win32 ------
1> TextWindow.cpp
1>e:\gamedev\c++\byte\byte\textwindow.cpp(19): error C2248: 'std::unique_ptr<_Ty>::unique_ptr' : cannot access private member declared in class 'std::unique_ptr<_Ty>'
1> with
1> [
1> _Ty=Element
1> ]
1> c:\program files (x86)\microsoft visual studio 10.0\vc\include\memory(2350) : see declaration of 'std::unique_ptr<_Ty>::unique_ptr'
1> with
1> [
1> _Ty=Element
1> ]
1> Generating Code...
1> Compiling...
1> Generating Code...
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
I have changed all references to the variable to std::unique_ptr. Here are the new files:
#include "TextWindow.hpp"
#include "TextElement.hpp"
#include <iostream>
TextWindow::TextWindow(const TextureHolder& textures, const FontHolder& fonts, sf::Window& windows, Fonts::ID fontID, sf::String text)
: mSprite(textures.get(Textures::WindowDefault))
, mHitpoints(10)
, mWindow(windows)
{
sf::FloatRect bounds = mSprite.getLocalBounds();
mSprite.setOrigin(bounds.width / 2.f, bounds.height / 2.f);
addElements(text, fonts.get(fontID));
}
void TextWindow::addElements(sf::String text, sf::Font font)
{
std::unique_ptr<TextElement> e(new TextElement(text, font, 10, xPos, yPos, 10, 10));
mElements.push_back(e);
}
void TextWindow::drawCurrent(sf::RenderTarget& target, sf::RenderStates states) const
{
target.draw(mSprite, states);
for(std::list<std::unique_ptr<Element>>::const_iterator iterator = mElements.begin(); iterator != mElements.end(); ++iterator)
{
//std::cout << "IN TEXTWINDOW PRINT ITERATOR" << std::endl;
(*iterator).get()->drawCurrent(target, states);
}
}
void TextWindow::updateCurrent(sf::Time dt)
{
}
From what you've posted above, it looks like
mElements
is astd::list<Element>
, and I'm assumingTextElement
inherits from a virtual base classElement
.This won't work.
mElements
will only storeElement
objects, not derived objects - this is known as the slicing problem.You need to change
mElements
tostd::list<unique_ptr<Element>>
(orshared_ptr
) so that the whole object can be stored in the list.