Witam,
Zabrałem się za dosyć ambitny, jak na mój poziom oczywiście, projekt. A mianowicie wpadłem na pomysł stworzenia w języku C++ prostego kreatora baz danych. Z założenia użytkownik miał mieć możliwość definiowania ile i jakiego typu kolumn będzie miała baza danych, którą chce zdefiniować. Przykładowo użytkownik chce stworzyć bazę danych, która będzie zawierała imię, nazwisko, datę urodzin i rozmiar buta, a potem, za pomocą tego samego programu stworzyć bazę, której kolumnami będą same inty. Niestety, nie udało mi się ominąć problemu z faktem, że w liście dwukierunkowej muszę mieć dokładnie określone, po jakich typach wyznacznik przechodzi... przynajmniej tak ja rozumiem mój problem. Poniżej zamieszczam kod, mam nadzieję, że ktoś ma pomysł jak to ominąć.
Baza.h:
#pragma once
#include "Kolumna.h"
template <typename T,typename D>
class Baza
{
public:
int l_kolumn;
int l_wierszy;
Kolumna<T>* poczatek;
Kolumna<D>* koniec;
string nazwa;
Baza();
~Baza() {};
friend Baza* utworz_nowa_baze();
};
template <typename T>
Baza::Baza():poczatek(0),koniec(0),nazwa("Nowa Baza"),l_kolumn(0),l_wierszy(0)
{}
template <typename T>
Baza* utworz_nowa_baze()
{
Baza nowa_b;
cout << "Jaka nazwe ma miec Twoja baza?" << endl; //Okno wprawadzenia nazwy bazy
cin >> nowa_b.nazwa;
cout << "Ile ma miec kolumn? " << endl;
cin >> l_kolumn;
//tworzenie kolumn
for(int i=0;i<l_kolumn;i++)
{
int b;
cout << "Jakiego typu ma to być kolumna? " << endl;
cin >> b;
// Sposób wyboru
// case 'b' : Kolumna<int>* wsk=new Kolumna<int>();
switch(b)
{
case 1:
Kolumna<int>* wsk=new Kolumna<int>();
break;
case 2:
Kolumna<float>* wsk=new Kolumna<float>();
break;
case 3:
Kolumna<string>* wsk=new Kolumna<string>();
break;
}
Kolumna<T>* wsk=new Kolumna<T>();
cout << "Jaka nazwe mma miec kolumna nr " << i+1 << " ?" << endl;
cin >> wsk->nazwa;
if(nowa_b.poczatek == NULL)
{
nowa_b.poczatek = wsk;
nowa_b.koniec = wsk;
}
else
{
nowa_b.koniec->nastepny=wsk;
wsk->poprzedni=nowa_b.koniec;
nowa_b.koniec = wsk;
}
}
}
Kolumna.h: (tu jest chyba największy problem)
#include "Pole.h"
template <typename T,typename C,typename D>;
class Kolumna
{
public:
static int l_wierszy;
string nazwa;
Pole<T>* poczatek;
Pole<T>* koniec;
Kolumna<D>* poprzedni_k;
Kolumna<C>* nastepny_k;
Kolumna();
~Kolumna();
bool isempty();
void add(T item);
void removeFirst();
void removeChosen(int x);
void print();
};
template <typename T,typename C,typename D>
Kolumna<T>::Kolumna():poczatek(NULL),koniec(NULL)
{}
template <typename T,typename C,typename D>
Kolumna<T>::~Kolumna()
{
while(poczatek!=NULL)
this->removeFirst();
}
template <typename T,typename C,typename D>
bool Kolumna<T>::isempty()
{
return poczatek == NULL;
}
template <typename T,typename C,typename D>
void Kolumna<T>::add(T item) // dodawanie sortowane
{
Pole<T>* wsk=new Pole<T>(item);
if(poczatek == NULL)
{
poczatek = wsk;
koniec = wsk;
}
else
{
Pole<T>* temp=poczatek;
while (temp != NULL)
temp=temp->nastepny;
wsk->poprzedni=temp;
temp->nastepny=wsk;
}
}
template <typename T,typename C,typename D>
void Kolumna<T>::removeFirst()
{
if(!(this->isempty()))
{
Pole<T>* wsk=poczatek;
poczatek=poczatek->nastepny;
poczatek->poprzedni=NULL;
delete wsk;
}
}
template <typename T,typename C,typename D>
void Kolumna<T>::removeChosen(int x)
{
if(this->isempty())
return;
Pole<T>* wsk=poczatek;
while(wsk->numer!=x)
wsk=wsk->nastepny;
wsk->poprzedni->nastepny=wsk->nastepny;
wsk->nastepny->poprzedni=wsk->poprzedni;
Pole<T>* zmiana_numeracji=wsk->nastepny;
delete wsk;
while (zmiana_numeracji!=NULL)
zmiana_numeracji->numer-=1;
}
template <typename T> // do zmiany
void Kolumna<T>::print()
{
Pole<T>* wsk=head;
while(wsk!=NULL)
{
cout << *wsk;
cout << endl;
wsk=wsk->nastepny;
}
}
Pole.h:
#pragma once
#include <iostream>
using namespace std;
template <typename T>
class Pole
{
public:
Pole* nastepny;
Pole* poprzedni;
int numer;
T dane;
Pole();
Pole(T nowe);
~Pole() {};
};
template <typename T>
Pole<T>::Pole():nastepny(0), poprzedni(0)
{
}
template <typename T>
Pole<T>::Pole(T nowe): dane(nowe), nastepny(0), poprzedni(0)
{
}