Skocz do zawartości
Zamknięcie Forum PC LAB

Szanowny Użytkowniku,

Informujemy, że za 30 dni tj. 30 listopada 2024 r. serwis internetowy Forum PC LAB zostanie zamknięty.

Administrator Serwisu Forum PC LAB - Ringier Axel Springer Polska sp. z o.o. z siedzibą w Warszawie: wypowiada całość usług Serwisu Forum PC LAB z zachowaniem miesięcznego okresu wypowiedzenia.

Administrator Serwisu Forum PC LAB informuje, że:

  1. Z dniem 29 listopada 2024 r. zakończy się świadczenie wszystkich usług Serwisu Forum PC LAB. Ważną przyczyną uzasadniającą wypowiedzenie jest zamknięcie Serwisu Forum PC LAB
  2. Dotychczas zamowione przez Użytkownika usługi Serwisu Forum PC LAB będą świadczone w okresie wypowiedzenia tj. do dnia 29 listopada 2024 r.
  3. Po ogłoszeniu zamknięcia Serwisu Forum od dnia 30 października 2024 r. zakładanie nowych kont w serwisie Forum PC LAB nie będzie możliwe
  4. Wraz z zamknięciem Serwisu Forum PC LAB, tj. dnia 29 listopada 2024 r. nie będzie już dostępny katalog treści Forum PC LAB. Do tego czasu Użytkownicy Forum PC LAB mają dostęp do swoich treści w zakładce "Profil", gdzie mają możliwość ich skopiowania lub archiwizowania w formie screenshotów.
  5. Administrator danych osobowych Użytkowników - Ringier Axel Springer Polska sp. z o.o. z siedzibą w Warszawie zapewnia realizację praw podmiotów danych osobowych przez cały okres świadczenia usług Serwisu Forum PC LAB. Szczegółowe informacje znajdziesz w Polityce Prywatności

Administrator informuje, iż wraz z zamknięciem Serwisu Forum PC LAB, dane osobowe Użytkowników Serwisu Forum PC LAB zostaną trwale usunięte ze względu na brak podstawy ich dalszego przetwarzania. Proces trwałego usuwania danych z kopii zapasowych może przekroczyć termin zamknięcia Forum PC LAB o kilka miesięcy. Wyjątek może stanowić przetwarzanie danych użytkownika do czasu zakończenia toczących się postepowań.

Temat został przeniesiony do archiwum

Ten temat przebywa obecnie w archiwum. Dodawanie nowych odpowiedzi zostało zablokowane.

januzi

c++ lista niejednorodna (faq)

Rekomendowane odpowiedzi

Jakis czas temu bylo pytanie o tworzenie listy obiektow, ktore sa roznych typow. Na mnie padlo napisanie czegos podobnego i oto wyniki :) Moze komus sie przyda.

 

#include <vector>

#include <iostream>

 

using namespace std ;

 

// predefiniowany rodzaj

int IN_Przes = 1 ;

int IN_For = 2 ;

int IN_ForEnd = 3 ;

 

/** \brief Klasa podstawowa, dzięki niej można tworzyć kolejkę.

* Jest ona "zanużona" w pozostałych klasach, dzięki czemu można określić

* rodzaj instrukcji i pobrać z kolejki odpowiednią klasę.

*/

class Instr_Podst {

public:

/** Zwracamy typ intrukcji. W klasie podstawowej jest równy 0.

* @return 0

*/

virtual int TypInstr() const = 0 ;

/** Destruktor

*/

virtual ~Instr_Podst() { } ;

} ;

 

/** \brief Klasa instrukcji ruchu IRb1400.

* Do dyspozycji są 3 instrukcje : MoveJ, MoveL, MoveC.

*/

class Instr_Ruchu: public Instr_Podst {

private:

/** Określa rodzaj ruchu */

int _rodzaj ;

public:

/** Konstruktor. Przez niego możemu przekazywać parametry do

* obiektu.

*/

Instr_Ruchu( int a = 0 ) { _rodzaj = a ; }

/** Zwraca typ instrukcji.

* @return IN_Przes

*/

int TypInstr() const { return IN_Przes ; }

/** Zwraca referencję do rodzaju

* @return &_rodzaj

*/

int &Rodzaj() { return _rodzaj ; }

} ;

 

/** \brief Klasa instrukcji początku i parametrów pętli.

* Określamy ilość powtórzeń następujących po niej instrukcji.

*/

class Instr_Petli_Start: public Instr_Podst {

private:

/** Określa ilość powtórzeń pętli */

int _liczba_powtorzen ;

public:

/** Zwraca typ instrukcji.

* @return IN_For

*/

int TypInstr() const { return IN_For ; }

/** Zwraca referencję do licznika

* @return &_liczba_powtorzen

*/

int &Licznik() { return _liczba_powtorzen ; }

} ;

 

/** \brief Klasa instrukcji końca pętli.

* Pętla powraca do miejsca wystąpienia Instr_Petli_Start

*/

class Instr_Petli_Stop: public Instr_Podst {

public:

/** Zwraca typ instrukcji.

* @return IN_ForEnd

*/

int TypInstr() const { return IN_ForEnd ; }

} ;

 

vector<Instr_Podst *> lista ;

 

int main()

{

lista.push_back(new Instr_Ruchu( 1 )) ;

lista.push_back(new Instr_Ruchu( 3 )) ;

int i ;

for( i = 0 ; i < lista.size() ; i++ ) {

int rodzaj = lista->TypInstr() ;

if( rodzaj == 1 ) {

Instr_Ruchu instr = (*(Instr_Ruchu *)(lista)) ;

cout << instr.Rodzaj() << endl ;

((Instr_Ruchu *)(lista))->Rodzaj() = 4 ;

}

}

char znak ;

cin >> znak ;

for( i = 0 ; i < lista.size() ; i++ ) {

int rodzaj = lista->TypInstr() ;

if( rodzaj == 1 ) {

Instr_Ruchu instr = (*(Instr_Ruchu *)(lista)) ;

cout << instr.Rodzaj() << endl ;

}

else cout << "Inna" << endl ;

}

char znak2 ;

cin >> znak2 ;

return 0 ;

}

 

// wynik

// 1

// czeka na klawisz i enter

// Inna

// Inna

// czeka na klawisz i enter

 

lista.push_back(new Instr_Ruchu( 2 )) ; // wrzucamy na liste nowy element, od razu w konstruktorze przekazujemy jeden z parametrow

lista->TypInstr() podaje numer, w kazdej klasie dziedziczacej musi byc zdefiniwana ta funkcja, wartosc bedzie pozwala okreslic na co nalezy zrzutowac

 

Instr_Ruchu instr = (*(Instr_Ruchu *)(lista)) ; // tutaj rzutujemy na odpowiedni typ

((Instr_Ruchu *)(lista))->Rodzaj() = 4 ; // a tak mozemy modyfikowac wartosc parametrow danego obiektu

 

Wszystko polega na tym, ze klasy pochodne maja w sobie jedna, wspolna klase. Dzieki temu mozemy wrzucic na liste wskaznik do klasy podstawowej zanurzonej w klasach pochodnych.

 

wiecej do przeczytania:

http://www-h.eng.cam.ac.uk/help/tpl/langua...++/tic0245.html

http://www.google.pl/search?hl=pl&q=Virtua...btnG=Szukaj&lr=

 

Edit: poprzednio bylo case, nie jest prawidlowe w przypadku wielu warunkow. Kompilator zabrania stosowac case dla wyluskiwanych instrukcji.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

kolejke juz mamy, dodaje sie elementy i kasuje, ale jak zmienic ?

 

Powiedzmy, ze jedna z klas potomnych mamy oznaczona jako Instr_Ruchu_C.

 

int Program::Dodaj_RuchC( Wektor6 arg1, Wektor6 arg2, int index )

{

int i ;

if( index == -1 ) { // sprawdzamy czy na koniec

lista.push_back(new Instr_Ruchu_C()) ; // wrzucamy

i = lista.size() - 1 ; } // ustawiamy i na ostatni element

else {

Instr_Podst *el = lista[index] ; // pobieramy wskaznik

lista[index] = (new Instr_Ruchu_C()) ; // podmieniamy element

delete( el ) ; // usuwamy wskaznik

i = index ; // i na zmieniony element

}

// wykonujemy operacje na obiekcie

((Instr_Ruchu_C *)(lista))->Q1() = arg1 ;

((Instr_Ruchu_C *)(lista))->Q2() = arg2 ;

return i ;

}

 

 

Wazne jest, zeby nie stracic informacji o elemencie. Sama zamiana wskaznika na liscie skonczyla by sie tak, ze mielibysmy "sierote". Dlatego tez nalezy zapamietac w ktorym miejscu znajdowal sie poprzedni obiekt, podmienic go, a nastepnie oczyscic pamiec ze starego obiektu.

 

Jeszcze jedna sprawa, wskaznik mamy do klasy podstawowej. Jak to sie dzieje, ze przy kasowaniu znika tez cala reszta, czyli obiekt z klasy pochodnej ? Sprawia to slowo kluczowe virtual, dzieki niemu wyrzucany jest i srodek obiektu (Instr_Podst) jak i Instr_Ruchu_C i kazda kolejna.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

  • Ostatnio przeglądający   0 użytkowników

    Brak zarejestrowanych użytkowników przeglądających tę stronę.

×
×
  • Dodaj nową pozycję...