Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Tworzenie tablicy wskaźników obiektu

Ostatnio zmodyfikowano 2022-02-19 20:01
Autor Wiadomość
tomasz.tomasz
Temat założony przez niniejszego użytkownika
Tworzenie tablicy wskaźników obiektu
» 2017-02-14 00:18:43
Witam. Jestem początkującym programistą i chciałem rozwiązać pewne zadanie ale natrafiłem na problem.
Treść zadania to:
Zdefiniować klasę bazową Wielokat i dwie dziedziczące z niej klasy pochodne Prostokat i Trojkat. Do klas pochodnych wprowadzić odpowiednie składowe reprezentujące boki tych figur. W klasie bazowej zdefiniować abstrakcyjną funkcję wirtualną ObliczObwod i przeciążyć ją w klasach pochodnych. W programie głównym zadeklarować tablicę wskaźników  obiektów klasy Wielokat (50 elementów)  i zrealizować obsługę następujących opcji:
C - utworzenie nowego obiektu klasy Prostokat i wpisanie jego wskaźnika
      do kolejnej pozycji tablicy,
T - utworzenie nowego obiektu klasy Trojkat i wpisanie jego wskaźnika
      do kolejnej pozycji tablicy,
O - obliczenie i wyświetlenie sumy obwodów wszystkich figur zawartych w tablicy,
R - odczytanie danych opisujących Wielokąty z pliku dyskowego (zapytać o nazwę
      pliku),
Z - zapis danych opisujących Wielokąty do pliku dyskowego (zapytać o nazwę pliku),
K - koniec programu.

Mój problem polega na tym, że nie wiem jak wykonać operacje dla pkt C i T. Oto kod wypłakany przeze mnie:

C/C++
#include <iostream>
#include <conio.h>
#include <cstdlib>
#include <string>
using namespace std;

class Wielokat
{
public:
    virtual void oblicz_obwod() = 0;
    virtual void tworzenie() = 0;
};

class Trojkat
    : public Wielokat
{
    float a, b, c;
    string nazwa_troj;
   
public:
   
    void tworzenie()
    {
        cout << "Tworzysz obiekt klasy 'Prostokat'" << endl;
        cout << "Podaj nazwe obiektu: " << endl;
        cin >> nazwa_troj;
        cout << "Podaj wartosci bokow: " << endl;
        cin >> a >> b >> c;
        cout <<& a;
    }
   
    void oblicz_obwod()
    {
        cout << "Obwod trojkata wynosi: " << a + b + c << endl;
    }
   
    Trojkat()
    {
        a = 0;
        b = 0;
        c = 0;
        nazwa_troj = "brak nazwy";
    }
};

class Prostokat
    : public Wielokat
{
    float x, y, z, q;
    string nazwa_pros;
   
public:
   
    void tworzenie()
    {
        cout << "Tworzysz obiekt klasy 'Prostokat'" << endl;
        cout << "Podaj nazwe obiektu: " << endl;
        cin >> nazwa_pros;
        cout << "Podaj wartosci bokow: " << endl;
        cin >> x >> y >> z >> q;
       
        // cout<<&x;
    }
   
    void oblicz_obwod()
    {
        cout << "Obwod prostokata wynosi: " << x + y + z + q << endl;
    }
   
    void show()
    {
        cout << "wyswietl nazwe" << nazwa_pros << endl;
        cout << "wyswietl x" << x << endl;
        cout << "wyswietl y" << y << endl;
        cout << "wyswietl z" << z << endl;
        cout << "wyswietl q" << q << endl;
    }
   
    Prostokat()
    {
        x = 0;
        y = 0;
        z = 0;
        q = 0;
        nazwa_pros = "brak nazwy";
    }
};


int main()
{
    char litera;
    int i = 0;
    //Wielokat *tab[5];
    Wielokat * wsk;
   
    do {
        cout << endl << endl;
        cout << "Wpisz co chcesz wykonac: " << endl << endl;
        cout << " C - utworzenie nowego obiektu klasy Prostokat i wpisanie jego wskaznika do tablicy" << endl;
        cout << " T - utworzenie nowego obiektu klasy Trojkat i wpisanie jego wskaznika do tablicy" << endl;
        cout << " O - obliczenie i wyswietlenie sumy obwodow wszystkich figur zawartych w tablicy" << endl;
        cout << " R - odczytanie danych opisujacych Wielokaty z pliku dyskowego" << endl;
        cout << " Z - zapis danych opisujacych Wielokaty do pliku dyskowego" << endl;
        cout << " K - koniec programu" << endl << endl;
       
        cin >> litera;
       
        if( litera == 'C' )
        {
            Prostokat nowy;
            wsk = & nowy;
            wsk->tworzenie();
            //   cout<<wsk;
           
        }
        else if( litera == 'T' )
        {
            Trojkat nowy;
            nowy.tworzenie();
        }
        else if( litera == 'O' )
        {
            //     for (int i=0; i<5; i++)
            //          tab[i].show();
        }
        else if( litera == 'K' )
        {
            exit( 0 );
        }
       
        i++;
    } while( 1 );
   
   
    return 0;
}

Dopiero się uczę więc proszę o jakieś przystępne wytłumaczenie.
Pozdrawiam.
P-157684
Nazgul
» 2017-02-14 01:08:34
masz klase Wielokat
masz dwie pochodne: Prostokat i Twojkat

no to masz:
C/C++
#include <vector>

///
std::vector < Wielokat *> tablica;
tablica.push_back( new Prostokat() );
tablica.push_back( new Trojkat() );

tablica[ 0 ].oblicz_obwod(); // oblicza obwod tak jakby to byl prostokat
tablica[ 1 ].oblicz_obwod(); // oblicza obwod tak jakby to byl trojkat
for( unsigned int i = 0; i < tablica.size(); i++ )
     delete tablica[ i ];

warunkiem, który musi być spełniony - klasy pochodne nie mogą dodawać swoich zmiennych do obiektu, bo operator przypisania się posypie.

także najlepiej jak zrobisz
C/C++
#include <vector>
class Wielokat
{
public:
    virtual float oblicz_obwod() = 0;
protected:
    std::vector < float > boki;
};

class Trojkat
    : public Wielokat
{
public:
    Trojkat( float a, float b, float c ) { boki.push_back( a ); boki.push_back( b ); boki.push_back( c ); }
    ~Trojkat() {
        boki.clear();
    }
    float oblicz_obwod() { return boki[ 0 ] + boki[ 1 ] + boki[ 2 ]; }
   
};

class Prostokat
    : public Wielokat
{
public:
    Prostokat( float a, float b ) { boki.push_back( a ); boki.push_back( a ); boki.push_back( b ); boki.push_back( b ); }
    ~Prostokat() {
        boki.clear();
    }
    float oblicz_obwod() { return boki[ 0 ] + boki[ 1 ] + boki[ 2 ] + boki[ 3 ]; }
   
};

int main()
{
    std::vector < Wielokat *> tablica;
    tablica.push_back( new Trojkat( 1, 2, 3 ) );
    tablica.push_back( new Prostokat( 3, 8 ) );
   
    float o_t = tablica[ 0 ]->oblicz_obwod();
    float o_p = tablica[ 1 ]->oblicz_obwod();
    for( unsigned int i = 0; i < tablica.size(); i++ )
         delete tablica[ i ];
   
    return 1;
}
P-157686
Nazgul
» 2017-02-14 01:23:41
napiszę ci jeszcze że wektory można zapisywać jako:

C/C++
#include <fstream>

void save( std::vector < float >& tablica ) {
    std::ofstream plik( "nazwa.format", std::ios::binary );
    unsigned int size = tablica.size();
    plik.write(( char * ) & size, sizeof( unsigned int ) ); //zapisuje w pliku (adres bajtu, ilość bajtów) w tym przypadku zapisze nam rozmiar tablicy
    plik.write(( char * ) & tablica[ 0 ], size * sizeof( float ) ); // w vectorze wszystko zapisane jest w pamięci liniowo, więc ten zapis powinien działać
    return;
}

void load( std::vector < float >& tablica ) {
    std::ifstream plik( "nazwa.format", std::ios::binary );
    unsigned int size;
    plik.read(( char * ) & size, sizeof( unsigned int ) ); //wszystuje z pliku (adres pod który wczytać, ilość bajtów do wczytanie) wczytujemy rozmiar tablicy
    tablica.resize( size ); // rezerwujemy pamięć dla tablicy
    plik.read(( char * ) & tablica[ 0 ], size * sizeof( float ) ); // wczytujemy wszystko do tablicy
    return;
}

uzupełnij sobie swój kod
P-157687
tomasz.tomasz
Temat założony przez niniejszego użytkownika
» 2017-02-15 23:55:15
Wszystko działa jak należy. Dziękuję bardzo za pomoc
P-157792
michal11
» 2017-02-16 00:03:50
C/C++
int main()
{
        std::vector < Wielokat *> tablica;
        tablica.push_back( new Trojkat( 1, 2, 3 ) );
        tablica.push_back( new Prostokat( 3, 8 ) );
       
        float o_t = tablica[ 0 ]->oblicz_obwod();
        float o_p = tablica[ 1 ]->oblicz_obwod();
        return 1;
}

taki kod to wyciek pamięci (aczkolwiek na większości systemów operacyjnych nie aż tak bardzo szkodliwy). Jeżeli alokujesz pamięć i używasz gołych wskaźników to musisz tez ją zwalniać deletem. Albo lepiej użyć smart pointerów i się nie przejmować

c++11:
C/C++
#include <memory>

int main()
{
        std::vector < std::unique_ptr < Wielokat > > tablica;
        tablica.push_back( new Trojkat( 1, 2, 3 ) );
        tablica.push_back( new Prostokat( 3, 8 ) );
       
        float o_t = tablica[ 0 ]->oblicz_obwod();
        float o_p = tablica[ 1 ]->oblicz_obwod();
        return 1;
}

lub c++14:
C/C++
#include <memory>

int main()
{
        std::vector < std::unique_ptr < Wielokat > > tablica;
        tablica.push_back( std::make_unique < Trojkat >( 1, 2, 3 ) );
        tablica.push_back( std::make_unique < Prostokat >( 3, 8 ) );
       
        float o_t = tablica[ 0 ]->oblicz_obwod();
        float o_p = tablica[ 1 ]->oblicz_obwod();
        return 1;
}
P-157794
Nazgul
» 2017-02-16 02:03:30
Tak tak, bardzo przepraszam za wprowadzenie w błąd, już uzupełniłem kod
P-157798
Karo_G
» 2022-02-19 20:00:33
P-179295
Karo_G
» 2022-02-19 20:01:16
Hej, tomasz.tomasz,  mam to samo zadanie. Dokładnie to samo. Jako, że nigdzie indziej go nie widziałam to istnieje duża możliwość, że mamy tego samego prowadzącego. Czy ten sposób rozwiązania zaliczył Ci to zadanie?
P-179296
« 1 »
  Strona 1 z 1