2013-03-27 3 views
0

Ответил: Благодаря @AndyProwl, указывая на некоторые вещи для меня, я выяснил, что проблема была в моей функции ScreenImage.Update(). Я набросился туда и обратно на запись реализации для этой функции (поскольку ScreenImage не нужно обновлять, его просто нужно нарисовать) и как-то случайно оставил функцию обновления на моем интерфейсе, когда я удалил реализацию ...Использование унаследованного класса в функции?

ДАЙТЕ, ЧТОБЫ ПРЕДУПРЕЖДЕНИЕ ДЛЯ ВАС ДЕТЕЙ. ~ Чем больше вы знаете, ~

Оригинал Вопрос:

Я сделать игру, и у меня есть Screen объект, который отслеживает предметы на одном экране (то есть варианты изображения, текст, меню, и т.д.). Моя цель состоит в том, чтобы передать эти элементы в Screen в виде абстрактного ScreenElements объекта, который мог бы, в свою очередь, определяются как более конкретные объекты, как ScreenImage или ScreenText т.д.

Я прошел через головную боль, пытаясь получить вектор (в основном рассматривая его как стек для ScreenElements), чтобы играть хорошо с разными унаследованными классами, сделав его вектором указателей на базовый объект, но тогда это означает, что я должен объявлять объекты, наследующие от ScreenElements вне функции, поэтому указатель не становится недействительным, когда декларация выходит за пределы области видимости. Итак, я сделал функцию в объекте Screen, чтобы позволить мне «AddElement», и я думал, что тот же самый метод указателя будет работать ... по-видимому, этого не происходит.

Вот мой исходный код, чтобы все прояснить. Это Screen.h.

#ifndef SCREEN_H 
#define SCREEN_H 

#include <vector> 

#include "ScreenElement.h" 

class Screen 
{ 
protected: 
    bool enabled; 

    std::vector<ScreenElement*> screen_elements; 
public: 
    //Gameloop Functions 
    void Init(); 
    void Update(int ticks); //Enabled will likely determine if this is called 
    void Draw(); //And this perhaps on a visible bool 
    void Destroy(); 

    //Concept functions 
    //void TransitionIn(data); 
    //void TransitionOut(data); 

    void AddElement(ScreenElement *Element); //function in question 

    //Allow external use of enabled feature 
    void ToggleEnable(bool Enabled) { enabled = Enabled; } 
    bool IsEnabled() { return enabled; } 
}; 

#endif // SCREEN_H 

И мой Screen.cpp файл

#include "Screen.h" 

void Screen::Init() 
{ 
    enabled = true; 
} 

void Screen::Update(int ticks) 
{ 
    for(int i = 0; i < screen_elements.size(); i++) 
     screen_elements[i]->Update(ticks); 
} 

void Screen::Draw() 
{ 
    for(int i = 0; i < screen_elements.size(); i++) 
     screen_elements[i]->Draw(); 
} 

void Screen::Destroy() 
{ 
    screen_elements.clear(); 
} 

void Screen::AddElement(ScreenElement *Element) 
{ 
    screen_elements.push_back(Element); 
} 

Мне нужно AddElement работать с любой унаследованной формой ScreenElement, таких как ScreenImage, например, и хранить его в вектор.

EDIT: Я думаю, я должен также добавить некоторый исходный код из класса ScreenElement. Когда я попытался добавить виртуальный деструктор, он вызвал еще одну ошибку в дополнение к первой, которая, по-видимому, связана с конструктором наследуемого класса (в функции ScreenImage :: ScreenImage() неопределенная ссылка на «vtable для ScreenImage»). Так вот мой ScreenElement.h

#ifndef SCREENELEMENT_H 
#define SCREENELEMENT_H 

#include "Globals.h" 

class ScreenElement 
{ 
protected: 
    s_Position screen_position; 

    bool enabled; 
public: 
    virtual void Update(int ticks) {} 
    virtual void Draw() {} 
    virtual void Destroy() {} 

    void ToggleEnable(bool Enabled) { enabled = Enabled; } 
    bool IsEnabled() { return enabled; } 
}; 

#endif // SCREENELEMENT_H 

Который в свою очередь, был использован для создания ScreenImage.h

#ifndef SCREENIMAGE_H 
#define SCREENIMAGE_H 

#include "Globals.h" 
#include "ScreenElement.h" 
#include "SpriteSheet.h" 

class ScreenImage: public ScreenElement 
{ 
private: 
    SpriteSheet *sprite_sheet; 

    int sprite_sheet_frame; 
public: 
    void Init(SpriteSheet *Sprite_Sheet, float X, float Y, int SpriteSheetFrame = 0); 
    void Update(int ticks); 
    void Draw(); 
    void Destroy(); 
}; 

#endif // SCREENIMAGE_H 

И имеет свои собственные реализации для базовых функций в ScreenImage.cpp.

+1

«* Я думал, что тот же метод указателя будет работать ... по-видимому, это не так. *" - Так в чем проблема? –

+0

Наследуете ли вы «ScreenImage» или «ScreenText» от «ScreenElement»? Как вы создаете экраны? Представленная здесь информация ничего не говорит об этом. – Arun

+0

@AndyProwl Когда я передаю указатель «ScreenElement» через функцию, он не примет указатель на унаследованный «ScreenImage», хотя теоретически они должны быть одинаковыми. Таким образом, функция «AddElement()» просто говорит: «Нет приемлемого преобразования из« ScreenImage »в« ScreenElement »или что-то в этом роде. – AniMerrill

ответ

0

After initializing an instance of Screen called SplashScreen and a ScreenImage called SplashScreen_Image, I use "SplashScreen.AddElement(&ScreenImage);" Then it throws me an error about having 'undefined reference to "vtable for ScreenImage"

Судя по ошибке вы сообщаете, проблема, кажется, что вы предоставили декларацию, но не определения, для некоторой виртуальной функции вашего класса.

Например, пытаясь скомпилировать следующий код будет производить очень похожую ошибку:

struct X 
{ 
    virtual void foo() { } 
}; 

struct Y : X 
{ 
    virtual void foo(); // Missing definition... 
}; 

int main() 
{ 
    Y y; 
    y.foo(); // The compiler will complain about undefined reference 
      // to vtable for Y... 
} 

Вот соответствующий live example.

+0

Я добавил исходный код моего класса там, где сейчас находится редактирование. Я никогда не объявлял конструктора или деструктора, потому что до настоящего времени ни один из них не нужен для дизайна моей игры. – AniMerrill

+0

@AniMerrill: И вы дали определение для всех виртуальных функций-членов? –

+0

Да, хотя в базовом классе они просто {}, потому что я не хочу, чтобы они ничего не делали. Но в ... Дерьмо. Да, видимо, я оставил Update без изменений. Теперь я чувствую себя глупо. – AniMerrill

Смежные вопросы