| Bimbol Temat założony przez niniejszego użytkownika | Szablon klasy, dla tablicy wielowymiarowej » 2013-08-08 23:39:08 Witam, natrafiłem na dosyć kłopotliwą sytuację. Mianowicie, polecenie zadania brzmi: (Bardzo trudne ) Dodaj do specjalizacji TArray<TArray<TYP> > przeciążony operator [], który będzie działał w ten sam sposób, jak dla zwykłych wielowymiarowych tablic języka C++. Wskazówka: operator ten będzie wobec tablicy używany dwukrotnie. Pomyśl więc, jaką wartość (obiekt tymczasowy) powinno zwracać jego pierwsze użycie, aby drugie zwróciło w wyniku żądany element tablicy. Kod: #include <iostream>#include <memory.h>
 
 using namespace std;
 
 template < typename TYP > class TArray
 {
 static const unsigned DOMYSLNY_ROZMIAR = 5;
 protected:
 TYP * m_pnTablica;
 unsigned m_uRozmiar;
 public:
 explicit TArray( unsigned uRozmiar = DOMYSLNY_ROZMIAR )
 : m_uRozmiar( uRozmiar )
 , m_pnTablica( new TYP[ uRozmiar ] )
 { }
 TArray( const TArray & );
 
 ~TArray() { delete[] m_pnTablica; }
 TYP Pobierz( unsigned uIndeks ) const
 {
 if( uIndeks < m_uRozmiar )
 return m_pnTablica[ uIndeks ];
 else
 return 0;
 
 }
 bool Ustaw( unsigned uIndeks, TYP nWartosc )
 {
 if( uIndeks >= m_uRozmiar ) return false;
 
 m_pnTablica[ uIndeks ] = nWartosc;
 return true;
 }
 unsigned Rozmiar() const { return m_uRozmiar; }
 TYP & operator []( unsigned uIndeks ) { return m_pnTablica[ uIndeks ]; }
 
 
 template < typename U >
 TArray < TYP >& operator =( TArray < U >& );
 };
 
 template < typename TYP >
 TArray < TYP >::TArray( const TArray & aTablica )
 {
 m_uRozmiar = aTablica.m_uRozmiar;
 m_pnTablica = new TYP[ m_uRozmiar ];
 memcpy( m_pnTablica, aTablica.m_pnTablica, m_uRozmiar * sizeof( TYP ) );
 }
 
 template < typename TYP >
 template < typename U >
 TArray < TYP >& TArray < TYP >::operator =( TArray < U >& aTablica )
 {
 
 delete[] m_pnTablica;
 
 m_uRozmiar = aTablica.Rozmiar();
 m_pnTablica = new TYP[ m_uRozmiar ];
 
 for( unsigned i = 0; i < m_uRozmiar; ++i )
 m_pnTablica[ i ] = aTablica[ i ];
 
 return * this;
 }
 
 template < typename TYP > class TDynamicArray
 : public TArray < TYP >
 {
 public:
 bool ZmienRozmiar( unsigned );
 };
 
 template < typename TYP > bool TDynamicArray < TYP >::ZmienRozmiar( unsigned uNowyRozmiar )
 {
 if( !( uNowyRozmiar > this->m_uRozmiar ) ) return false;
 
 TYP * pNowaTablica = new TYP[ uNowyRozmiar ];
 memcpy( pNowaTablica, this->m_pnTablica, this->m_uRozmiar * sizeof( TYP ) );
 delete[] this->m_pnTablica;
 this->m_pnTablica = pNowaTablica;
 this->m_uRozmiar = uNowyRozmiar;
 return true;
 }
 
 
 
 template < typename TYP > class TArray < TArray < TYP > >
 {
 static const unsigned DOMYSLNY_ROZMIAR = 5;
 private:
 
 TYP * m_pTablica;
 
 unsigned m_uRozmiarX;
 unsigned m_uRozmiarY;
 
 public:
 
 explicit TArray( unsigned uRozmiarX = DOMYSLNY_ROZMIAR, unsigned uRozmiarY = DOMYSLNY_ROZMIAR )
 : m_uRozmiarX( uRozmiarX )
 , m_uRozmiarY( uRozmiarY )
 , m_pTablica( new TYP[ uRozmiarX * uRozmiarY ] )
 { }
 
 ~TArray() { delete[] m_pTablica; }
 
 
 
 unsigned RozmiarX() const { return m_uRozmiarX; }
 unsigned RozmiarY() const { return m_uRozmiarY; }
 
 
 
 TYP & operator ()( unsigned uX, unsigned uY ) { return m_pTablica[ uY * m_uRozmiarX + uX ]; }
 TYP & operator []( unsigned uIndex )
 {
 static TYP uIndexY = uIndex;
 return uIndex;
 }
 };
 
 int main()
 {
 cout << "Hello world!" << endl;
 TArray < TArray < int > > Array( 1, 1 );
 cout << Array( 0, 0 ) << endl;
 cout << Array[ 1 ][ 1 ] << endl;
 return 0;
 }
 
Problem w tym, że kod się nawet nie kompiluje, bo i niby czemu skoro to jest dwuwymiarowa tablica, działająca jako jedno wymiarowa. Więc jak można tutaj zastosować dwa operatory []? | 
|  | 
| DejaVu | » 2013-08-09 14:42:58 1. Podaj błędy kompilacji.
 2. Szablonowe typy danych często trzeba poprzedzać słowem kluczowym  typename  deklaracjach/definicjach metod. | 
|  | 
| DejaVu | » 2013-08-09 14:44:36 | przeciążony operator [], który będzie działał w ten sam sposób, jak dla zwykłych wielowymiarowych tablic języka C++. 
 | 
 
Nie da się przeciążyć operatora [] tak, aby miał coś wspólnego z wielowymiarowymi tablicami. Da się co najwyżej obsługiwać wywołania tak jak dla tablicy jednowymiarowej.
 /edit:
 Tak swoją drogą ten kod woła o pomstę do nieba - nie wiem co Ciebie zainspirowało do używania słowa kluczowego static wewnątrz operatora [], ale to jest z definicji złe. | 
|  | 
| Bimbol Temat założony przez niniejszego użytkownika | » 2013-08-09 15:27:32 | | przeciążony operator [], który będzie działał w ten sam sposób, jak dla zwykłych wielowymiarowych tablic języka C++. 
 
 | 
 Nie da się przeciążyć operatora [] tak, aby miał coś wspólnego z wielowymiarowymi tablicami. Da się co najwyżej obsługiwać wywołania tak jak dla tablicy jednowymiarowej.
 | 
 No właśnie, więc to zadanie jest bez sensu.  | /edit:
 
 Tak swoją drogą ten kod woła o pomstę do nieba - nie wiem co Ciebie zainspirowało do używania słowa kluczowego static wewnątrz operatora [], ale to jest z definicji złe.
 | 
 Szczerze zainspirowało mnie to:  | Wskazówka: operator ten będzie wobec tablicy używany dwukrotnie. Pomyśl więc, jaką wartość (obiekt tymczasowy) powinno zwracać jego pierwsze użycie, aby drugie zwróciło w wyniku żądany element tablicy. | 
 Czyli wychodzi na to, że moje kombinowanie było złe i nie potrzebne. | 
|  | 
| DejaVu | » 2013-08-09 15:50:34 template < typename TYP >class TArray
 {
 public:
 TYP & operator []( unsigned uIndeks ) { return m_pnTablica[ uIndeks ]; }
 };
 
To jest wystarczający typ.
 Zobacz sobie np. na std::vector. Napiszesz:
 std::vector < std::vector < int > > v;
 std::cout << v[ 0 ][ 0 ];
 
i działa. Napiszesz:
 TArray < TArray < int > > v;
 std::cout << v[ 0 ][ 0 ];
 
i również działa (bo pierwszy operator[] zwraca referencję na obiekt TAray<int> , a drugi operator zwraca referencję na int ). | 
|  | 
| Monika90 | » 2013-08-09 15:53:13 Twój kod jest bardzo nieczytelny ze względu na te dziwne prefiksy, ale jeżeli dobrze rozumiem co chesz osiągnąć za pomocą jawnej specjalizacji TArray, to operator [] powinien mieć taką deklarację: TArray < TYP >& operator []( unsigned uIndex );
/EDIT A ponieważ powyższe wymaga zmiany reprezentacji, to może lepiej spróbować TYP * operator []( unsigned uIndex );
 | 
|  | 
| Bimbol Temat założony przez niniejszego użytkownika | » 2013-08-09 16:06:27 | template < typename TYP >class TArray
 {
 public:
 TYP & operator []( unsigned uIndeks ) { return m_pnTablica[ uIndeks ]; }
 };
 
To jest wystarczający typ.
 
 
 
 Zobacz sobie np. na std::vector. Napiszesz:
 
 
 std::vector < std::vector < int > > v;
 std::cout << v[ 0 ][ 0 ];
 
i działa. Napiszesz:
 
 
 TArray < TArray < int > > v;
 std::cout << v[ 0 ][ 0 ];
 
i również działa (bo pierwszy operator[] zwraca referencję na obiekt TAray<int>, a drugi operator zwraca referencję na int).
 | 
 Vektora jeszcze nie przerabiałem, a o drugiej sytuacji wiem. Jednak to jest zadanie i trzymałem się treści.  Specjalizacje szablonu TArray<TArray<TYP> > pisał autor kursu. | Twój kod jest bardzo nieczytelny ze względu na te dziwne prefiksy, ale jeżeli dobrze rozumiem co chesz osiągnąć za pomocą jawnej specjalizacji TArray, to operator [] powinien mieć taką deklarację: 
 TArray < TYP >& operator []( unsigned uIndex );
/EDIT
 A ponieważ powyższe wymaga zmiany reprezentacji, to może lepiej spróbować
 
 TYP * operator []( unsigned uIndex );
 | 
 Spróbuję. | 
|  | 
| Monika90 | » 2013-08-09 16:08:58 @DejaVu | To jest wystarczający typ. | 
 Powinien być wystarczający ale nie jest, bo nie da się skonstruować tablicy, której drugi wymiar byłby różny od 5. | 
|  | 
| « 1 »  2 3 |