Инициализировать и объявить динамически несколько переменных случайных объектов в цикле в C ++ - PullRequest
0 голосов
/ 01 ноября 2018

Это мой код:

#include <cstdlib>
#include <ctime>
#include <stdio.h>
#include <vector>
#define ENTITY(A) entity##A
#define ALM(A) alm##A

struct TEntity{
private:
    int sumx;
    int sumy;
    const char * rep;
    int m_ix;
    int m_iy;
public:
    TEntity(int x, int y, int sum_x, int sum_y, const char * txt);
};

TEntity::TEntity(int x, int y, int sum_x, int sum_y, const char * txt) {
    m_ix = x;
    m_iy = y;
    sumx = sum_x;
    sumy = sum_y;
    rep = txt;
}

class IAlmacenable {
private:
    void * element;
public:
    IAlmacenable(void * e);
    IAlmacenable();
    void * getValue();
};

IAlmacenable::IAlmacenable(void *e) {
    element = e;
}

IAlmacenable::IAlmacenable() {
    element = nullptr;
}

void * IAlmacenable::getValue() {
    return element;
}

class TList {
private:
     std::vector<IAlmacenable*> elementos;
     int position;
public:
    TList();

    int Size();

    int Push(IAlmacenable* psz);
};

TList::TList() {
    elementos = std::vector<IAlmacenable*>();
    position = 0;
}

int TList::Size() {
    return elementos.size();
}

int TList::Push(IAlmacenable* psz) {
    int res = 0;
    if (elementos.size() >= elementos.max_size()) {
        res = -1;
    }
    else {
        elementos.push_back(psz);
    }
    return res;
}

int main(){
    srand(time(NULL));

    TList *list = new TList();
    //we can put entities in the list and the rest will be filled up to 5
    int size = list->Size();
    for(int i = size; i<5;i++){
        const char c[] = {(rand() % 2 ? 65 + rand() % 25 : 97 + rand() % 25), '\0'};
        TEntity ENTITY(i)(rand() % 10, rand() % 10, rand() % 5, rand() % 5, c);
        IAlmacenable ALM(i)(&ENTITY(i));
        list->Push(&ALM(i));
        size++;
    }
    //do things like printing their value...
    delete list;
    return 0;
}

Мне нужно создавать новую переменную каждый раз, когда она запускает строку «TEntity ENTITY (i)», проблема в том, что он всегда создает одну и ту же переменную, я думаю, это потому, что он создает переменную entityi и, следовательно, он перезаписывает одну и ту же переменную, кроме того, кажется, что генерируемая случайная величина всегда одинакова, поскольку все сущности имеют одинаковые значения по всем его параметрам. Переменная c создает переменную const char * random между a-z, A-Z, я не помещаю код печати, потому что это не нужно, так что я могу сделать? Есть ли способ динамически создавать переменные сущностей, значения которых являются случайными?

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

#include <cstdlib>
#include <ctime>
#include <stdio.h>
#include <vector>
#include <conio.h>
#include <windows.h>

struct TEntity{
private:
    int sumx;
    int sumy;
    const char * rep;
    int m_ix;
    int m_iy;
public:
    TEntity(int x, int y, int sum_x, int sum_y, const char * txt);
    void movimiento();
    void pinta();
};

TEntity::TEntity(int x, int y, int sum_x, int sum_y, const char * txt) {
    m_ix = x;
    m_iy = y;
    sumx = sum_x;
    sumy = sum_y;
    rep = txt;
}

void TEntity::movimiento() {
    m_ix += sumx;
    m_iy += sumy;
}

void TEntity::pinta() {
    gotoxy(static_cast<short int>(m_ix), static_cast<short int>(m_iy));
    printf("%s", rep);
}

void gotoxy(short int x, short int y)
{ 
    COORD pos = {x, y};
    HANDLE output = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleCursorPosition(output, pos);
}

void clear()
{
    system("cls");
}

class IAlmacenable {
private:
    void * element;
public:
    IAlmacenable(void * e);
    IAlmacenable();
    void * getValue();
};

IAlmacenable::IAlmacenable(void *e) {
    element = e;
}

IAlmacenable::IAlmacenable() {
    element = nullptr;
}

void * IAlmacenable::getValue() {
    return element;
}

class TList {
private:
     std::vector<IAlmacenable*> elementos;
     int position;
public:
    TList();

    int Size();

    int Push(IAlmacenable* psz);

    IAlmacenable* First();

    IAlmacenable* Next();
};

TList::TList() {
    elementos = std::vector<IAlmacenable*>();
    position = 0;
}

int TList::Size() {
    return elementos.size();
}

int TList::Push(IAlmacenable* psz) {
    int res = 0;
    if (elementos.size() >= elementos.max_size()) {
        res = -1;
    }
    else {
        elementos.push_back(psz);
    }
    return res;
}

IAlmacenable* TList::First() {
    IAlmacenable* res;
    if (elementos.empty()) {
        res = nullptr;
    }
    else {
        res = elementos.front();
        position = 1;
    }
    return res;
}

IAlmacenable* TList::Next() {
    IAlmacenable* res;
    if (elementos.empty()) {
        res = nullptr;
    }
    else {
        int pos = position;
        int size = elementos.size();
        if (pos < size) {
            res = elementos.at(position);
            position++;
        }
        else {
            res = this->First();
        }
    }
    return res;
}

int main(){
    srand(time(NULL));

    TList *list = new TList();
    //we can put entities in the list and the rest will be filled up to 5
    int size = list->Size();
    for(int i = size; i<5;i++){
        const char c[] = {(rand() % 2 ? 65 + rand() % 25 : 97 + rand() % 25), '\0'};
        TEntity *entity = new TEntity(rand() % 10, rand() % 10, rand() % 5, rand() % 5, c);
        IAlmacenable *alm = new IAlmacenable(entity);
        list->Push(alm);
        size++;
    }
    while(true){
        clear();
        for (int i = 0; i < size; i++) {
            reinterpret_cast<TEntity *>(list->Next()->getValue())->pinta();
            reinterpret_cast<TEntity *>(list->Next()->getValue())->movimiento();
        }
        Sleep(2000);
    }
    delete list;
    return 0;
}

enter image description here

1 Ответ

0 голосов
/ 01 ноября 2018

Здесь есть некоторая путаница.

Некоторые баллы:

  1. Макрос не соответствует назначению, как вы уже знаете; вы просто создаете имя переменной entityi каждый раз;
  2. Это не имеет значения! В любом случае, объект существует только в течение итерации цикла; C ++ не позволяет вам создавать несколько объектов с одинаковыми именами одновременно. На самом деле вы можете избавиться от всего макроса и просто вызвать объект entity;
  3. Теперь, когда это не так, вы получаете повторяющиеся результаты, потому что храните указатель на каждую итерацию этой локальной переменной & mdash; в каждом случае это висящий указатель на уничтоженный объект. Не храните висячие указатели!

Вы можете либо:

  • Динамически размещать объекты, которые вы добавляете в список, или
  • Хранить реальные объекты, а не указатели на объекты.

В любом случае имя локальной области не имеет значения и, разумеется, не нуждается в многократном изменении для каждой итерации цикла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...