• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

dynamiczne wskazywanie nazw zmiennych

Object Storage Arubacloud
0 głosów
660 wizyt
pytanie zadane 19 lipca 2016 w C i C++ przez niezalogowany
Witam, czy jest możliwość aby w cpp miała miejsce taka sytuacja:

załóżmy mam dwadzieścia struktur na kształt: level1 level2 level3 level4 itd... które zawierają potrzebne mi dane. I czy zamiast pisać mnóstwo linii do tworzenia tych poszczególnych struktur (no może nie mnóstwo no ale jednak trochę) to jest możliwość abym za pomocą zmiennej np. actual_level tworzył te struktury? Trochę pogmatwałem ale może taki przykład zobrazuje moją myśl:

actual level = 4

(level+int_to_string(actual_level)) (level+int_to_string(actual_level));

co jest równoznaczne z:

level4 level4;

Jeśli coś takiego jest niemożliwe to jak się uporać z "automatyzacją" nazw?
komentarz 19 lipca 2016 przez maly Nałogowiec (37,190 p.)
To co chcesz otrzymać nie jest możliwe w C++.
Mam pytanie, czym się różnią te wszystkie levele od siebie?
komentarz 19 lipca 2016 przez niezalogowany

przykładowy poziom, pierwszy raz robię grę z wieloma poziomami więc uprzedzam, że mogę zabierać się od d*py strony

struct level1
{
    int tilemap1[25][24]=
    {
    {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,1},
    {1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1},
    {1,1,1,1,1,1,1,1,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1},
    {1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1},
    {1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3},
    {4,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1},
    {1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1},
    {1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
    {50,550,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},//linia z danymi
    };
};

 

4 odpowiedzi

+2 głosów
odpowiedź 19 lipca 2016 przez MetRiko Nałogowiec (37,110 p.)
edycja 19 lipca 2016 przez MetRiko

Zawsze możesz wykorzystać dziedziczenie.. Jest to proste i skuteczne rozwiązanie.
Tworzysz bazową klasę Level.. następnie w osobnych plikach jej podklasy (W tym wypadku Level_1, Level_2.. itd.).
Jeżeli będzie chciał aktywować jakiś level.. to w klasie (nazwijmy to) Manager będziesz mógł ustawić wskaźnik CurrentLevel na odpowiedni poziom. Ponad to w klasie Manager byłaby funkcja aktualizująca i rysująca poziom, na który aktualnie wskazuje CurrentLevel.
Przykład:

class Manager
{
   Level* CurrentLevel;
   Level* Levels[2];
   Manager()
   {
      Levels[0]=new Level_1();
      Levels[1]=new Level_2();
   }
   void Update()
   {
      CurrentLevel->Update();
   }
   void CurrentLevel(int NumLevel)
   {
      CurrentLevel=Levels[NumLevel];
   }
};

 

komentarz 19 lipca 2016 przez niezalogowany

Za pomocą zmiennej globalnej actual_level i wtórnym wywołaniem maina po przejściu poziomu chciałem oszukać system ale on oszukał mnie. 

 switch(actual_level)
    {
    case 1:
        {
            level1 level;
            break;
        }
    case 2:
        {
            level2 level;
            break;
        }
    case 3:
        {
            level3 level;
            break;
        }
    case 4:
        {
            level4 level;
            break;
        }

    default :
        {
         //domyslnie jakis komunikat o błędzie
            level1 level;
            break;
        }
    }



Character character(level.tilemap[24][0],level.tilemap[24][1]);

I wywala mi błąd, że level nie został zadeklarowany... tylko już nawet na siłe wcisnąłem do switcha do default aby on został zadeklarowany i w każdym możliwym wariancie przecież pojawi się level a jednak program tego nie uznaje. Czy jest jakiś sposób bym to obszedł swoim sposobem?

komentarz 20 lipca 2016 przez MetRiko Nałogowiec (37,110 p.)
edycja 20 lipca 2016 przez MetRiko

Musisz zadeklarować wszystkie zmienne (Levele) wcześniej.. Nie ma innej opcji.. Chyba, że na prawdę nie chcesz zachowywać poprzednich poziomów to możesz zrobić tak:
WAŻNE: Wywołanie tego kodu zawsze sprawia, że tworzy się nowa klasa Level, a stara zostaje usunięta.. Zadbaj o to, by kod ten wywoływał się tylko gdy nastąpi warunek przejścia poziomu!

Level *CurrentLevel=nullptr;

#define SET_LEVEL(Name) if(CurrentLevel) delete CurrentLevel; CurrentLevel = new Name ; break;

switch(actual_level)
    {
    case 1: SET_LEVEL(level1)
            /* Taki zapis kryje się pod makrem SET_LEVEL(level1)
            if(CurrentLevel) delete CurrentLevel;
            CurrentLevel = new level1;
            break;
            */            
    case 2: SET_LEVEL(level2)
    case 3: SET_LEVEL(level3)
    case 4: SET_LEVEL(level4)

 
    default : SET_LEVEL(level1)
              //domyslnie jakis komunikat o błędzie
#undef SET_LEVEL
+1 głos
odpowiedź 19 lipca 2016 przez niezalogowany
a nie lepiej na tablicy??
komentarz 19 lipca 2016 przez niezalogowany
co masz konkretnie na myśli?
komentarz 19 lipca 2016 przez niezalogowany

załóżmy mam dwadzieścia struktur na kształt: level1 level2 level3 level4 itd..
 

mam na myśli lvl[20];

komentarz 19 lipca 2016 przez niezalogowany
bym musiał mieć 1 strukturę i 20 "obiektów" tej struktury, ja potrzebuję 20 struktur, każda w sobie ma już od razu zapisane potrzebne danie, po wykorzystaniu są usuwane i pobierana jest następna struktura
komentarz 19 lipca 2016 przez niezalogowany
dynamiczna alokacja tablicy 2-wymiarowej??
komentarz 19 lipca 2016 przez niezalogowany
no dobra ale to nie rozwiązuje problemu wskazywania nazw
0 głosów
odpowiedź 19 lipca 2016 przez criss Mędrzec (172,590 p.)

Tzn. w zależności od wartości zmiennej actual level utworzyć obiekt odpowiedniej struktury? Nie badzo. Raczej musiałbyś to jakoś obejść. Proponuje specjalizacje template (chociaż raczej niekonieczne), switch i preprocesor do switcha.

struct LevelBase
{
   // metody wirt. które będziesz przeciążał w specjalizacjach template
  // po prostu uzywaj tej klasy jako czesci wspolnej wszystkich specjalizacji template-a Level
};

template<std::size_t N> struct Level : public LevelBase
{
   static_assert(N >= 1 && N <= 20, "Nope.");
};

template<> struct Level<1> : public LevelBase
{
   // ...
};

template<> struct Level<2> : public LevelBase
{
   // ...
};

// itd.

std::shared_ptr<LevelBase> createLevel(std::size_t _n)
{

#define CASE(n) case n: return std::make_shared(Level<n>()); break;

   switch(_n)
   {
     CASE(1)
    // itd.
   }

#undef CASE
}

Szczerze mówiąc dałbym se spokój i spróbował napisać tą gierke jakoś inaczej :P

komentarz 19 lipca 2016 przez niezalogowany

Być może przykład takiej struktury pomoże jakoś naprowadzić na problem:

przykładowy poziom, pierwszy raz robię grę z wieloma poziomami więc uprzedzam, że mogę zabierać się od d*py strony

struct level1
{
    int tilemap1[25][24]=
    {
    {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,1},
    {1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1},
    {1,1,1,1,1,1,1,1,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1},
    {1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1},
    {1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3},
    {4,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1},
    {1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1},
    {1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
    {50,550,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},//linia z danymi
    };
};
0 głosów
odpowiedź 20 lipca 2016 przez maly Nałogowiec (37,190 p.)

Jeśli w strukturze miałaby być wyłącznie tablica to nie ma sensu jej używać.
Wystarczy bezpośrednio użyć tablic, coś w ten deseń.

#include <iostream>

typedef int map_t[3][3];

map_t map1 = {
	{0,1,2},
	{3,4,5},
	{6,7,8}
};
map_t map2 = {
	{0,1,2},
	{0,1,2},
	{0,1,2}
};
map_t map3 = {
	{0,1,2},
	{0,1,2},
	{0,1,2}
};

map_t &get_map(int index)
{
	map_t *maps[] = {&map1, &map2, &map3};
	return *maps[index];
}

int main()
{
	int current_map_index = 0;

	map_t &current_map = get_map(current_map_index);

	current_map[1][2] = 666;
	int i = current_map[1][2];
	
	std::cout << i;
}

 

Podobne pytania

0 głosów
3 odpowiedzi 259 wizyt
pytanie zadane 9 września 2016 w C i C++ przez Knayder Nałogowiec (37,640 p.)
+1 głos
1 odpowiedź 831 wizyt
pytanie zadane 24 września 2017 w Systemy operacyjne, programy przez niezalogowany
0 głosów
0 odpowiedzi 127 wizyt
pytanie zadane 2 grudnia 2020 w Algorytmy przez wojtek_suchy Mądrala (6,880 p.)

92,572 zapytań

141,422 odpowiedzi

319,643 komentarzy

61,959 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...