Im создание классов Label и Button. Ярлык в основном служит текстом, который прикреплен к Button, а Button имеет текстуру кнопки и еще несколько вещей.SFML C++ рисование в RenderWindow чистой виртуальной функции сбой выполнения
Я хотел автоматизировать вещи, поэтому вам не нужно вызывать метод рисования каждой кнопки отдельно, поэтому я создал класс ButtonManager, у которого есть вектор и статическая функция члена-члена.
Проблема заключается в том, что вектор содержит класс интерфейса, а не обычный (для будущих расширений типов кнопок).
Перед тем, как описать проблему, позволяет увидеть код:
Файл с основным интерфейсом для всех кнопок:
class ButtonManager;
class ButtonBase{
typedef ButtonManager Manager;
public:
virtual int getType() = 0;
virtual void draw(sf::RenderWindow& target) = 0;
};
это очень просто один
Файл с ButtonManager (Немного больше):
class ButtonManager{
typedef ButtonBase* ptr;
static std::vector<ptr> container;
inline static ptr& __at(uint index)
{
if (index > container.size()) throw std::exception("bad index");
return container[index];
}
static void __push(const ptr& Pointer) { container.push_back(Pointer); }
static void __pop() { container.pop_back(); }
/*
Private to hide them from potentional unintended push or pop
*/
public:
enum{
DRAW_ALL = -1
};
static void draw(sf::RenderWindow& target, uint toDraw = DRAW_ALL)
{
std::cout << "container: " << container.size() << "\n";
if (toDraw == DRAW_ALL)
for(auto& a : container)
{
a->draw(target);
}
else
container.at(toDraw)->draw(target);
}
struct ClassImpl{
inline static ptr& at(uint index) { return ButtonManager::__at(index); }
inline static void push(const ptr& Pointer) { ButtonManager::__push(Pointer); }
inline static void pop() { ButtonManager::__pop(); }
};
};
std::vector<ButtonManager::ptr> ButtonManager::container;
и, наконец, файл, связанный с самой кнопкой:
class Button final : public ButtonBase{
typedef ButtonBase parent;
mutable Label label;
mutable sf::Texture texture;
mutable sf::Sprite buttonImage;
mutable std::function<void(Button&, ButtonState/* enum class */)> callBack;
public:
Button() {}
Button(const sf::Vector2f& position, const sf::Vector2f& size, const std::string& imagePath,\
sf::IntRect& rect/*unsued*/, std::function<void(Button&, ButtonState)> f_ptr,\
const Label& _label) : label(_label), callBack(f_ptr)
//some code
Manager::ClassImpl::push(this);
}
//copy construct
Button(const Button& b);
//copy assign
Button& operator=(const Button& b);
//move assign
Button(Button&& b);
//move construct
Button& operator=(Button&& b);
int getType()
{
return 1;
}
void draw(sf::RenderWindow& window)
{
window.draw(buttonImage);
window.draw(label.getText());
}
};
Примечание: Я попытался сделать ButtonManager :: PTR ВТН ButtonBase * и станд :: shared_ptr, без успеха
У меня есть проблема в том, что, когда я называю ButtonManager :: Жеребьевка (someSFMLWindow), когда он пытается вызвать a-> рисуем (цель), он будет писать в консоль:
R6025 - Вызов чисто виртуальной функции
и когда я отладки кода, появилась ошибка, когда первая строка кнопки: : draw был вызван (window.draw (buttonImage)).
Где проблема? какие-либо намеки, где проблема?
Почему бы не просто реализовать 'sf :: Drawable :: draw' в классе ButtonManager? – jready
Я не вижу, как бы вы хотели поместить его, потому что вы знаете, я мог бы просто перевернуть вектор и нарисовать вручную в основном, но я хочу автоматизировать все, поэтому вы просто вызываете ButtonManager :: draw (window) и его рисует все созданные кнопки edit: я пробовал, не думаю, что я не сделал – Creris
Если вы реализуете 'sf :: Drawable :: draw' в ButtonManager, вы можете' sf :: RenderWindow :: рисовать 'объект ButtonManager откуда угодно. Это определенно будет более однородным с тем, как все остальное делается в приложении SFML. Как вы пытались это сделать, и это не сработало? Если вы просто расширяете 'sf :: Drawable' из ButtonManager, у вас не должно быть проблем – jready