How to assemble a collection of derived objects, and use specific functions of each?

Asked

Viewed 64 times

2

I want to create a dynamic list that contains all Component derived objects.

I’m trying to do it this way:

map<string, Componente> tabuleiro_componentes;
tabuleiro_componentes.insert(make_pair('000',Peca(//Parametros)));
tabuleiro_componentes.insert(make_pair('001',Escudeiro(//Parametros)));

With this code I can add the components to the Map, he understands that the classes are daughters of Component. What I want to do is search the map for the string and use the unique methods of Peca and Squire, only that the only options shown are the methods of Component.

I believe it’s because Map is like <string, Componente>, I must try another approach or there is solution ?

Solution: I built a palliative solution using simple and dynamic_cast pointers: https://github.com/KaueAlves/Grimorie-Tabuleiro/tree/kaue-dev-dinamic_cast

The archive component. h:

#ifndef COMPONENTE_H
#define COMPONENTE_H

#include "Default.h"
#include "Posicao.h"

class Componente
{
protected:
    int id;
    Posicao pos;
    string nome;
    string tipo;
public:
    Componente(/* args */);
    ~Componente();
    Componente(int id, string nome, string tipo);
    // Gets
    Posicao getPosicao();
    string getTipo();
    string getNome();
    int getID();
    // Sets 
    void setNome(string nome);
    void setID(int id);
};


#endif

The archive Peca. h:

#ifndef PECA_H
#define PECA_H

#include "default.h"
#include "Posicao.h"
#include "Componente.h"

using namespace std;

class Peca : public Componente
{
private:
    string sinal;
    Posicao pos;
    // Cor cor;
    int qntMovimentos, qntMaxMovimentos;
    pair<int,int> tamanho;
public:
    //Construtor - Destruidor
    Peca();
    Peca( Posicao pos, pair<int,int> tamanho);
    ~Peca();

    //Gets
    Posicao getPosicao();
    int getQntMaxMovimetnos();
    int getQntMovimentos();
    pair<int,int> getTamanho();
    string getSinal();

    //Sets
    void setPosicao(Posicao pos);
    void setQntMaxMovimentos(int qntMaxMovimentos);
    void setQntMovimentos(int qntMovimentos);
    void setTamanho(pair<int,int> tamanho);
    void setSinal(string sinal);

    //Funções
    string toString();
};

#endif

The archive Squire. h:

#ifndef Escudeiro_H
#define Escudeiro_H

#include "../Default.h"
#include "../Peca.h"

class Escudeiro : public Peca
{
private:
    /* data */
public:
    Escudeiro();
    ~Escudeiro();
    Escudeiro(Posicao pos, pair<int,int> tamanho);
    string toString();
};

#endif

1 answer

2


First mistake is that you are storing objects of one type in another type, this does not give the result you expect. If you reserve space for a type Componente and then put an object Peca that has a larger size, how do you expect the object to fit there? You are corrupting the memory and do not even know. The solution to this is to make a indirect. Using a pointer you ensure that every object in the structure is the same size, the size of a pointer, and the object with the die itself is somewhere else. Done this it is possible to work with different objects.

But you still have a problem when you pick up the object. You need to make a cast. When you take an element directly from a Componentethis object will be a Componente, so he can only access members of this type. As you know that it can be something more specific you can indicate to the compiler to see it as that specific object and then the members you want will be available. But there’s a problem: what kind are you going to turn into? There are objects of different types within this map, you can only transform it if you are sure that it is of the type in question, otherwise it will give error.

Behold Which type of smart pointer to choose?. And look for other questions on the subject. And Casting between base classes and derivatives?.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.