andrzejek97 Temat założony przez niniejszego użytkownika |
dynamiczna tablica obiektów, stos » 2017-04-22 17:55:58 Wita, mam problem z napisaniem programu, który ma implementować stos oparty o tablicę, otóż w zadaniu miałem stworzyć interfejs Stack zawierający wirtualne metody void push(Item* obj), void pop() oraz Item* get(), odpowiadające za: umieszczanie elementu na stosie, usunięcie elementu ze stosu oraz zwrócenie aktualnego elementu, klasę Item zawierającą pole name typu string i jednoargumentowy konstruktor tego samego typu, oraz klasę ArrayStack implementującą stos oparty o tablicę (tu mam problemy), klasa ta ma dziedziczyć po interfejsie Stack, jej konstruktor ma przyjmować argument typu int opisujący maksymalny rozmiar stosu. Czy dobrze rozumiem, że ta tablica ma być tablicą obiektów typu Item, jeśli tak to dlaczego takie przydzielenie pamięci nie działa, wiem, że jeśli dopiszę w klasie Item konstruktor domyślny to zadziała, lecz czy to jest odpowiednie rozwiązanie problemu, wklejam kod, w komentarz dałem metody push, pop i get, mam nadzieję, że zadziałają po rozwiązaniu problemu z przydzieleniem pamięci, a może źle zrozumiałem treść zadania, proszę o odpowiedź. #include<iostream>
using namespace std; class Item; class Stack { public: virtual void push( Item * obj ) = 0; virtual void pop() = 0; virtual Item * get() = 0; };
class Item { string name; public: Item( string _name ) : name( _name ) { } }; class ArrayStack : public Stack { int top; Item * tablicaStos; public: ArrayStack( int rozmiar ) { tablicaStos = new Item( "nazwa" )[ rozmiar ]; top = - 1; } virtual void push( Item * obj ) { } virtual void pop() { } virtual Item * get() { } }; int main() { return 0; }
|
|
j23 |
» 2017-04-22 18:14:42 dlaczego takie przydzielenie pamięci nie działa, wiem, że jeśli dopiszę w klasie Item konstruktor domyślny to zadziała, lecz czy to jest odpowiednie rozwiązanie problemu |
Nie działa, bo nie ma takiej konstrukcji new[], żeby tworzyć tablice obiektów wywołując konstruktory parametryczne. Musisz dodać konstruktor domyślny. Inna opcja to użyć placement new: int rozmiar; ...
ArrayStack( int n ) : rozmiar( n ) { tablicaStos =( Item * ) new char[ n * sizeof( Item ) ]; top = - 1; }
~ArrayStack() { delete[]( char * ) tablicaStos; }
...
void push( Item * obj ) { int i = top + 1; if( i == rozmiar ) throw std::out_of_range( "overflow!" ); new(( char * ) & tablicaStos[( top = i ) ] ) Item( * obj ); }
void pop() { if( top < 0 ) throw std::out_of_range( "underflow!" ); tablicaStos[ top-- ].~Item(); }
Choć i tu musisz dodać konstruktor kopiujący. |
|
andrzejek97 Temat założony przez niniejszego użytkownika |
» 2017-04-22 18:57:42 bardzo dziękuję ,a czy takie rozwiązanie przejdzie, wolałbym ominąć dodawanie konstruktora kopiującego #include<iostream>
using namespace std; class Item; class Stack { public: virtual void push( Item * obj ) = 0; virtual void pop() = 0; virtual Item * get() = 0; };
class Item { string name; public: Item( string _name ) : name( _name ) { } Item() { } }; class ArrayStack : public Stack { int top; Item * tablicaStos; public: ArrayStack( int rozmiar ) { tablicaStos = new Item[ rozmiar ]; top = - 1; } virtual void push( Item * obj ) { tablicaStos[ ++top ] = * obj; } virtual void pop() { tablicaStos[ top-- ]; } virtual Item * get() { return & tablicaStos[ top ]; } }; |
|
j23 |
» 2017-04-22 19:08:22 Po dodaniu konstruktora domyślnego przejdzie. tylko push i pop powinny sprawdzać, czy nie przekraczają zakresu tablicy (patrz mój przykład).
push według mnie powinna przyjmować const referencję zamiast tego wskaźnika.
PS. wcześniej popieprzyło mi się z tym konstruktorem kopiującym. Nie musisz go definiować przy takiej konstrukcji klasy Item. |
|
j23 |
» 2017-04-22 20:16:18 Jeszcze jedna rzecz: dodaj destruktor, który zwalnia pamięć tablicaStos. Tu jeszcze poprawiony destruktor z mojego przykładu: ~ArrayStack() { for( int i = 0; i <= top; ++i ) tablicaStos[ i ].~Item(); delete[]( char * ) tablicaStos; }
|
|
andrzejek97 Temat założony przez niniejszego użytkownika |
» 2017-04-22 21:02:06 Dziękuję, w poleceniu jest, że push ma przyjmować wskaźnik, więc tego zmienić nie mogę, get też później zwraca wskaźnik virtual Item * get() { return & tablicaStos[ top ]; } |
|
andrzejek97 Temat założony przez niniejszego użytkownika |
» 2017-04-23 12:53:03 |
|
« 1 » |