• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Wskaźniki wewnątrz klas oraz konstruktor

Object Storage Arubacloud
0 głosów
217 wizyt
pytanie zadane 18 września 2020 w C i C++ przez stanleylbn Nowicjusz (180 p.)

Dzień dobry. Mam problem ze wskaźnikami i konstruktorem. Gdy tylko włączam ten program, od razu się zamyka okno windowsowe, natomiast gdy wyłącze wszystkie deklaracje i użycie wskaźników to działa poprawnie. Czy ktoś mógłby zerknąc gdzie popełniłem błędy i czy w ogole jest zasadne tutaj stosowanie wskaźników? Dopiero się ich ucze stąd ta amatorka. 

A w programie chodzi o dodawanie kilku Aut: atrybuty to marka, przebieg, liczba pasazerow, kolor, a także chciałem dodać dodatkową funkcję dodającą wartość przebiegu i właśnie tam pojawia się błąd.

#include <iostream>
using namespace std;
class Klasa
{
private:
    string marka;
    int licznik;
    int l_pasazerow;
    string kolor;
    int *add;
public:
    void dodaj_auto();
    int zwieksz_przebieg();
    void wyswietl();

    Klasa(string="Marka", int=10, int=5, string="Kolor", int =1);//Konstruktor
    ~Klasa(); //Destruktor
};

int main()
{
    Klasa obiekt[4];
    for (int i=0; i<4; i++)
    {
        obiekt[i].dodaj_auto();
        obiekt[i].zwieksz_przebieg();
    }
    for (int j=0; j<4; j++)
    {
        obiekt[j].wyswietl();
    }

    return 0;
}

void Klasa::dodaj_auto()
{
    cout<<"Podaj marke: ";
    cin>>marka;
    cout<<"Podaj przebieg licznika: ";
    cin>>licznik;
    cout<<"Podaj liczbe pasazerow: ";
    cin>>l_pasazerow;
    cout<<"Podaj kolor: ";
    cin>>kolor;
    cout<<endl;
}

int Klasa::zwieksz_przebieg()
{
    cout<<"Ile dodac przebiegu: ";
    cin>>*add;
    licznik=licznik+*add;
    add=&licznik;
}

void Klasa::wyswietl()
{
    cout<<"Marka: "<<marka<<endl;
    cout<<"Przebieg licznika: "<<licznik<<endl;
    cout<<"Liczbae pasazerow: "<<l_pasazerow<<endl;
    cout<<"Kolor: "<<kolor<<endl;
    cout<<"Nowy przebieg to: "<<licznik+*add<<endl;
}

Klasa::Klasa(string m, int l, int p, string k, int a) // konstruktor
{
    marka=m;
    licznik=l;
    l_pasazerow=p;
    kolor=k;
    *add=a;
}

Klasa::~Klasa() //usuniecie konstruktora
{
}

 

2 odpowiedzi

0 głosów
odpowiedź 18 września 2020 przez adrian17 Ekspert (344,860 p.)
edycja 18 września 2020 przez adrian17

To nie ma związku z klasami, musisz powtórzyć wskaźniki.

Twój kod robi coś takiego:

int *add;
*add = 5;

Co nie ma sensu, bo próbujesz przypisać 5 w miejsce na które wskazuje wskaźnik... ale wskaźnik na nic konkretnego nie wskazuje.

komentarz 18 września 2020 przez TOM_CPP Pasjonat (22,640 p.)

Jest jeszcze gorzej. Wskaźnik wskazuje na losowe miejsce w pamięci, która jest następnie nadpisywana jakąś liczbą, czyli mamy UB.

komentarz 18 września 2020 przez stanleylbn Nowicjusz (180 p.)

@adrian17,

zamieniłem w linijce 72

    add=&a;

oraz w linijce 53

 

    licznik=&add;

Teraz działa, tylko, żepodczas wyswietlania nie pokazuje mi starej wartosci licznika, tylko 2x nowa.

komentarz 18 września 2020 przez tangarr Mędrzec (154,860 p.)
Zadaj sobie kilka pytań.
1. Co mają robić poszczególne funkcje?
2. Za co odpowiada zmienna add?
3. Dlaczego zmienna add jest wskaźnikiem?
komentarz 18 września 2020 przez stanleylbn Nowicjusz (180 p.)

znam odpowiedź na pierwsze pytanie, na drugie i trzecie już nie, bo dopiero się ucze tych wskaźników i chyba ich nie rozumiem. 

Edytowałem ten kod do postaci bez wskażników i tez konstutkora. Zmiany są w linijce 55 i 64

#include <iostream>
using namespace std;
class Klasa
{
private:
    string marka;
    int licznik;
    int l_pasazerow;
    string kolor;
    int add;
    int nowy_przebieg;

public:
    void dodaj_auto();
    int zwieksz_przebieg();
    void wyswietl();

    //Klasa(string="Marka", int=10, int=5, string="Kolor", int =1);//Konstruktor

    //~Klasa(); //Destruktor
};

int main()
{
    Klasa obiekt[1];
    for (int i=0; i<1; i++)
    {
        obiekt[i].dodaj_auto();
        obiekt[i].zwieksz_przebieg();
    }
    for (int j=0; j<1; j++)
    {
        obiekt[j].wyswietl();
    }

    return 0;
}

void Klasa::dodaj_auto()
{
    cout<<"Podaj marke: ";
    cin>>marka;
    cout<<"Podaj przebieg licznika: ";
    cin>>licznik;
    cout<<"Podaj liczbe pasazerow: ";
    cin>>l_pasazerow;
    cout<<"Podaj kolor: ";
    cin>>kolor;
}

int Klasa::zwieksz_przebieg()
{
    cout<<"Ile dodac przebiegu: ";
    cin>>add;
    nowy_przebieg=licznik+add;
}

void Klasa::wyswietl()
{
    cout<<"Marka: "<<marka<<endl;
    cout<<"Przebieg licznika: "<<licznik<<endl;
    cout<<"Liczbae pasazerow: "<<l_pasazerow<<endl;
    cout<<"Kolor: "<<kolor<<endl;
    cout<<"Nowy przebieg to: "<<nowy_przebieg<<endl;
}

No i teraz po namysle wydaje mi się że wskaźnik powinien wskazywać na adres zmiennej licznik.
Czyli

int *wsk=&licznik;

Czy tak? Proszę o jakoś podpowiedź, jak to powinienem rozegrać.

komentarz 18 września 2020 przez tangarr Mędrzec (154,860 p.)
Ja nie użyłbym wskaźnika w tej sytuacji. Nie rozumiem dlaczego próbowałeś go tam wcisnąć. Zastanawiam się czy ktoś ci kazał użyć wskaźników w tym programie, czy po prostu chciałeś je przetestować.

Nie rozumiem jeszcze kilku rzeczy w twoim programie:
1. Dlaczego zmienna add jest zmienną klasy a nie lokalną zmienną funkcji?
2. Jaki jest cel funkcji Klasa::zwieksz_przebieg()?
3. Co się powinno stać jeżeli wykonasz ją kilka razy?
4. Czy na pewno taki efekt chciałeś uzyskać?
0 głosów
odpowiedź 18 września 2020 przez TOM_CPP Pasjonat (22,640 p.)

Wywal wszystkie wskaźniki, nie musisz także mieć własnych konstruktorów ani destruktorów. Użyj kontenera vector oraz przeładowania operatora << do wypisywania na ekranie. Zobacz jak to może wyglądać:

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

struct Car
{
    string brand {"None"};
    string color {"None"};
    int mileage {0};
    int capacity {0}; // number of passengers

    friend ostream& operator<<( ostream& out , const Car& car )
    {
        out << "Brand = " << car.brand << " : color = " << car.color ;
        out << " : mileage = " << car.mileage << " : capacity = " << car.capacity;
        return out;
    }
};

class Garage
{
private:

    vector<Car> cars;

public:

    void add( const Car& car )
    {
        cars.push_back(car);
    }

    bool change_mileage( const string& name , int value )
    {
        auto iter {find_if( cars.begin(), cars.end(), [&]( const Car& car ) { return car.brand == name; } )};
        if( iter!=cars.end() ) iter->mileage += value;
        return iter!=cars.end();
    }

    friend ostream& operator<<( ostream& out , const Garage& garage )
    {
        for( const auto& car : garage.cars ) out << car << endl;
        return out;
    }

};

int main()
{
    Garage garage;
    garage.add( { "Mercedes","Red",120000,5 } );
    garage.add( { "Volvo","Silver",250000,5 } );
    garage.add( { "Audi","Green",45000,4 } );

    cout << garage << endl;

    cout << "Try to change mileage : " <<  ( garage.change_mileage("Volvo", -160000) ? "Success" : "Fail" ) << endl << endl;

    cout << garage << endl;

    return 0;
}

 

Podobne pytania

0 głosów
2 odpowiedzi 145 wizyt
pytanie zadane 20 listopada 2018 w C i C++ przez estewui Początkujący (270 p.)
0 głosów
4 odpowiedzi 16,792 wizyt
0 głosów
1 odpowiedź 313 wizyt
pytanie zadane 25 marca 2021 w C i C++ przez kacper1445 Gaduła (4,880 p.)

92,567 zapytań

141,420 odpowiedzi

319,615 komentarzy

61,952 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...