Witam
Czy macie pomysł jak zrobić cos takiego: potrzebuje przechowywać obiekty różnych typów, ale nie wiem jakie będą i ile ich będzie(co nie ma większego znaczenia). Jak to zrobić w c++?
ile ich będzie to nie problem (np. char* znaki=new char[ileichbedzie]; ) z tymi nieznanego typu obiektami nie wiem jak się uporać, coś mi to śmierdzi uniami ale pewny nie jestem... :]
Aby można było przechowywać dowolną liczbę obiektów, musisz użyć jakiejś dynamicznej struktury, np. listy.
Aby elementy były różne masz kilka możliwości:
a) lista ma wskaźnik do unii
b) lista ma wskaźnik do struktury, która pamięta rodzaj obiektu i wskaźnik do samego obiektu
c) lista ma wskaźnik typu (void *). Bezpośrenio pod tym wskaźnikiem musi być jakiś indentyfikator typu obiektu. A następnnie cała reszta obiektu.
Można by zrobić po prostu wskaźnik typu (void*) na obiekt. Ale co Ci z tego, że będziesz miał obiekt, jeżeli nie będziesz znał jego typu?
chodzi o to ze potrzebuje przechowywać powiedzmy w liscie obiekty roznych typow, albo wskazniki do nich i w momencie kompilacji nie wiadomo ile ich bedzie i jakich bada typow. Program ma wlasnie dodawac obiekty i okreslac ich typ. Czyli np:
dodaj costam int
dodaj costam string
itp
No to zrób tak jak wyżej napisałem. Ostrzegam tylko, że wrzucanie całkowicie dowolnych obiektów na listę jest bez sensu.
Możesz to zrobić np. tak(lista przechowująca inty i char*)
#define STRING_T 1
#define INT_T 2
/* element naszej listy */
struct lista_elem
{
int typ;
void *elem;
};
(...)
/* zwracanie elementu listy */
if (w->typ == STRING_T) return ((char*) elem);
else return (*((int*) elem));
Nie wiem jak bardzo złożony program piszesz. Jeśli bardzo to warto wypróbować gotowe rozwiązania: boost::any
To ja mam bardzo związane z tematem pytanie.
Taki przykład:
mam klase podstawową, czysto ABSTRAKCYJNĄ:
class Drzewo
{
public:
Drzewo(int size):wysokosc(size){};
virtual void pokaz()=0;
private:
float wysokosc;
};
i teraz jakies klasy pochodne, dziedziczące po drzewie:
class Sosna: public Drzewo
{
public:
Sosna(int size):Drzewo(size){};
void pokaz(){
cout << "Jestem sosna, bo mam igly\n";
};
};
class Lipa: public Drzewo
{
public:
Lipa(int size):Drzewo(size){};
void pokaz(){
cout << "Jestem lipa, bo mam liscie\n";
};
};
I teraz potrzebuje zrobić liste (kolejke, tablice, nie ważne), na której mogłbym przechowywać obiekty klas pochodnych od Drzewa.
std::list<Drzewo*> lista;
lista.push_back(new Sosna(3));
lista.front()->pokaz();
EEEEEE to do budy ma zapewne, a tam korzystac z list czy vector'ow nie mozna ;)
Zrob sobie jednokierunkowa lista wskaznikow na "Drzewo" i wsio.
STL owszem, działa, zrobiłem tak, ale wolałbym nie używać stl'a.
Do budy owszem, ale zadanie juz dawno zaliczone (własnie na STL'u). Teraz to sie pytam zupełnie z ciekawości.
Zwykła lista wskaźników nic nie da. Powiedzmy, że mam funkcje "bool dodaj(Drzewo* drzewo)", która dodaje mi wskaźnik na Drzewo do mojej listy (bazy danych).
No i teraz w głownym programie tworze sobie jakiś obiekt pochodny od Drzewa, dodaje go za pomocą tej funkcji do bazy danych. Niby wszystko w porządku, ale! Wystarczy, że w głownym programie zmienie jakieś pole tego obiektu i zmienia się on również w mojej bazie. A taka sytuacja nie ma prawa wystąpic! Moge też usunąć obiekt w głownym programie i wtedy w bazie robią sie krzaki ;).
Sedno sprawy jest w skopiowaniu obiektu, który może być dowolnego typu (pochodnego od Drzewo) i umieszczenie go poźniej (lub wskaźnika do tego skopiowanego) na liście (w bazie danych).
/Oczywiscie nazwy klas Drzewo, Lipa itp. są wymyślony tylko po to, zeby było łatwo wytłumaczyć o co mi chodzi./
EDIT:
Doszedłem wniosku, że jest to po prostu nie możliwe... W Javie owszem, ale nie w c++. STL również nie potrafi zrobić kopi obiektu pochodnego nie znając jego typu.
W związku z tym mam pytanie w jaki sposób wmiare sensownie wykonać taką baze danych? Zostaje tylko wywołanie "dodaj(new Lipa);" ??