jeudi 17 novembre 2022

Missing VTABLE error while creating an inventory system for my game [closed]

I am making an inventory system for my game, however I keep getting this error telling me I am missing vtables, however I define both Inventory::toString() and Item::toString() in my code.

Error :

2 warnings generated.
Undefined symbols for architecture arm64:
  "Item::toString() const", referenced from:
      Inventory::toString() const in Inventory-a887cf.o
  "vtable for Item", referenced from:
      Item::Item(Item const&) in Inventory-a887cf.o
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.

ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [all] Error 1

Inventory.h

#pragma once

#include "items/Item.h"

class Inventory
{
    private:
        Item** items;

        int max_size;
        int current_size;

        // Private Functions
        void initialize(const unsigned from = 0);
        void expand();

    public:
        // Constructor
        Inventory(unsigned max_size = 10);
        Inventory(const Inventory& other);
        ~Inventory();

        // Operators
        void operator = (const Inventory& other);
        Item& operator[] (const unsigned index);

        // Accessors
        const unsigned& size() const;
        const unsigned& capacity() const;
        Item& at(const unsigned index) const;


        // Modifiers


        // Public Functions
        void add(const Item& item);
        void remove(const Item& index);
        std::string toString() const;
};

Inventory.cpp

#include "Inventory.h"
#include <sstream>

// Public Functions
void Inventory::initialize(const unsigned from) {
    for(size_t i = 0; i < this->max_size; i++) {
        this->items[i] = nullptr;
    }
};

void Inventory::expand() {
    this->max_size *= 2;

    Item** temp = new Item*[this->max_size];
    for(size_t i = 0; i < this->max_size; i++) {
        temp[i] = this->items[i];
    }

    delete[] this->items;
    this->items = temp;

    this->initialize(this->current_size);
};

// Constructor
Inventory::Inventory(unsigned max_size) {
    this->max_size = max_size;
    this->current_size = 0;
    this->items = new Item*[max_size];

    this->initialize();
};

Inventory::Inventory(const Inventory& other) {
    this->max_size = other.max_size;
    this->current_size = other.current_size;
    this->items = new Item*[this->max_size];

    this->initialize();

    for(size_t i = 0; i < this->current_size; i++) {
        this->items[i] = other.items[i];
    }
};

// Destructor
Inventory::~Inventory() {
    for(size_t i = 0; i < this->max_size; i++) {
        delete this->items[i];
    }
    delete[] this->items;
};

// Operators
void Inventory::operator=(const Inventory& other) {
    if(this != &other) {
        for(size_t i = 0; i < this->current_size ; i++) {
            delete this->items[i];
        }
        delete[] this->items;

        this->max_size = other.max_size;
        this->current_size = other.current_size;
        this->items = new Item*[this->max_size];

        this->initialize();

        for(size_t i = 0; i < this->current_size; i++) {
            this->items[i] = other.items[i];
        }
    }
};

Item& Inventory::operator[](const unsigned index) {
    if(index < 0 || index >= this->current_size) {
        throw "Index out of bounds!";
    }
    return *this->items[index];
};

const unsigned& Inventory::size() const {
    return this->current_size;
};

const unsigned& Inventory::capacity() const {
    return this->max_size;
};

Item& Inventory::at(const unsigned index) const {
    if(index < 0 || index >= this->current_size) {
        throw "Index out of bounds!";
    }
    return *this->items[index];
}; 

// Functions
void Inventory::add(const Item& item) {
    if(this->current_size >= this->max_size) {
        this->expand();
    }
    this->items[this->current_size++] = new Item(item);
};

void Inventory::remove(const Item& index) {
    
};

std::string Inventory::toString() const {
    std::stringstream ss;

    for(size_t i = 0; i < this->current_size; i++) {
        ss << this->items[i]->toString() << std::endl;
    }

    return ss.str();
}

Item.h

#pragma once

#include <iostream>

enum ItemType
{
    MATERIAL = 0,
    TOOL = 1,
    FOOD = 2,
};

enum ItemRarity
{
    COMMON = 0,
    UNCOMMON = 1,
    RARE = 2,
    EPIC = 3,
    LEGENDARY = 4,
    HOLY_SHIT = 5,
};

class Item
{
    private:
        int id;
        unsigned type;
        unsigned rarity;
        unsigned value;

        std::string name;
        std::string description;

        void generate();

    public:
        // Constructor
        Item(std::string name, unsigned type, unsigned rarity, unsigned value, std::string description);
        
        // Destructor
        virtual ~Item();

        int size;
        bool isStackable;

        int max_stack_size;
        int current_stack_size;

        // Accessors
        const int& getId() { return this->id; }
        const unsigned& getType() { return this->type; }
        const unsigned& getRarity() { return this->rarity; }
        const unsigned& getValue() { return this->value; }
        const std::string& getName() { return this->name; }
        const std::string& getDescription() { return this->description; }

        // Functions
        const std::string toString() const;
};

Item.cpp

#include "Item.h"
#include <sstream>

void Item::generate() {
    
}

// Constructor
Item::Item(std::string name, unsigned type, unsigned rarity, unsigned value, std::string description) {
    this->name = name;
    this->description = description;
    this->id = id;
    this->type = type;
    this->rarity = rarity;
    this->value = value;
}

// Destructor
Item::~Item() {
    
}

// Accessors

const int & Item::getId() {
    return this->id;
}

const unsigned & Item::getType() {
    return this->type;
}

const unsigned & Item::getRarity() {
    return this->rarity;
}

const unsigned & Item::getValue() {
    return this->value;
}

const std::string & Item::getName() {
    return this->name;
}


const std::string & Item::getDescription() {
    return this->description;
}

// Functions
const std::string Item::toString() const {
    std::stringstream ss;

    ss << "Name: " << this->name 
    << " | Description: " << this->description 
    << " | Value: " << this->value 
    << " | Rarity: " << this->rarity << " | Type: " 
    << this->type;

    return ss.str();
}

I checked that both were defined and they are. I am confused as to what a vtable I have never seen an error like this before.

Aucun commentaire:

Enregistrer un commentaire