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

Dziedziczenie klas i zmiana wartości klasy bazowej

Ostatnio zmodyfikowano 2014-11-10 22:06
Autor Wiadomość
Atexor
Temat założony przez niniejszego użytkownika
Dziedziczenie klas i zmiana wartości klasy bazowej
» 2014-11-01 15:55:32
Witam, mam kilka klas pochodnych, które są dziedziczone z bazowej.

Istota mojego programu wymaga, aby zmienne i wartości odziedziczone w klasach pochodnych nie były "kopiami" z klasy bazowej, ale oryginalnymi elementami (coś jak referencja) i posługując się nimi, zmieniam wartości w klasie-matce.
Ewentualnie mieć te kopie w kalsach pochodnych, ale mieć też możliwość zmieniania w klasach pochodnych wartości zmiennych z klasy bazowej.

Próbowałem przy użyciu ampersanda &, lub przy użyciu operatora zasięgu klasa_podstawowa::nazwa_zmiennej w klasach pochodnych, ale bezskutecznie. Miałem albo błędy kompilacji przy pierwszym sposobie, albo w drugim operator zasięgu (jeśli faktycznie działał) korzystał z wartości podstawowych klasy bazowej (z konstruktora, jeszcze niezmienione metodami).

Wyczytałem o takim czymś jak przyjaźń między klasami. Czy jest to rozwiązanie mojego problemu lub czy można bez tego zrobić?

Pozdrawiam
P-119806
Monika90
» 2014-11-01 16:22:43
Nie rozumiem w czym problem. Przecież to działa
C/C++
class B
{
protected:
    int x;
};

class D
    : public B
{
public:
    void f()
    {
        x = 9; //możesz sobie używać do woli
    }
};

Inna sprawa że dane z dostępem protected to zły pomysł.
P-119809
Atexor
Temat założony przez niniejszego użytkownika
» 2014-11-01 17:03:51
A jaki powinien być dostęp? Publiczny?

Konkretnie chodzi mi o takie coś (trochę uproszczę dla pokazana problemu):

C/C++
class A
{
public:
    int zmienna; //w konstruktorze robię np. zmienna=25
};

class B
    : public A
{
    //...//
};

Klasa B przyjmuje zmienną=25 z klasy A.

W funkcji głównej programu main np. zrobimy:
C/C++
A obj_A;
B obj_B;

obj_B.zmienna += 100;

I teraz zmienna w obiekcie B wynosi 125, ale w obiekcie A nadal 25, a chciałbym aby też była 125. A zmieniając wartość zmiennej w obiekcie A chciałbym aby też się zmieniała w obiekcie B.

Dokładniej to mam do zrobienia "uproszczony system bankomatów". Załóżmy, że mam początkowe saldo 6000 tysięcy zł., z bankomatu PODSTAWOWEGO wypłacam 400zl i chciałbym, aby te saldo (5600) też się zmieniło w bankomacie NORMALNYM, a jak wybiorę potem 200 złotych w normalnym, to aby się zmieniło też w podstawowym i wynosiło 5400 zł. Zmienna saldo ma być "jedna" w klasie, ale kilka tych klas ma na niej operować.

Teraz mam taki problem, że mam tak jakby "2 konta niezależne o 2 saldach".
P-119812
Monika90
» 2014-11-01 17:16:03
A jaki powinien być dostęp? Publiczny?
prywatny

A wracając do tematu. To są dwa różne obiekty więc czego się spodziewałeś? Jeżeli saldo zrobisz składową statyczną, to bedzie jedno dla wszystkich obiektów klasy. Ale to nie jest właściwe rozwiązanie problemu. Prawdopodobnie właściwe rozwiązanie to klasa Konto i referencja do jednego i tego samego obiektu tej klasy we wszystkich bankomatach.
P-119815
Atexor
Temat założony przez niniejszego użytkownika
» 2014-11-01 17:19:52
To mógłbym w sumie do klasy abstrakcyjnej dodać te zmienne... Mogę tak? Tylko właśnie jak się odwoływać przez referencję w klasach? Jak już wyżej pisałem próbowałem za pomocą operatora zasięgu ::, czy ampersanda & (jak przy referencji/adresu wskaźników).

A zaprzyjaźnienie klas? Można tego użyć?
Nie mam tu zielonego pojęcia jak to rozwiązać...
P-119816
Atexor
Temat założony przez niniejszego użytkownika
» 2014-11-01 23:36:41
Mógłbym prosić o pomoc w rozwiązaniu tego problemu? Naprawdę bardzo mi na tym zależy.


Próbowałem użyć przyjaźni, zmiennej statycznej (z nią nawet się nie kompilowało) w klasie abstrakcyjnej i potem w "podstawowy", użycia operatora zasięgu ::,a także wskaźnika this w metodach (licząc, że w przypadku normalnego bankomatu będzie poprawnie nabijać "licznik", nie nabija, a w this-> w podstawowym nie robi żadnej różnicy). Ogólnie to nic nie działa.


W związku z tym dziedziczeniem między klasami pojawił się także inny problem z tym związany (prosiłbym o nieoddzielanie/niezamykanie tematu, bo wszystko się sprowadza do dziedziczenia).

Otóż w moim programie jest "limit na wypłacanie z bankomatu". W przypadku podstawowego na 1000zł, na normalnego na 10.000. Czyli jeśli łącznie wypłacę 1000zł z podstawowego, to więcej już nie mogę.

I w przypadku podstawowego bankomatu "naliczanie limitu działa poprawnie (dałem dużo coutów, do odnalezienia problemu, proszę zwrócić uwagę na te ostrzałkowane)
http://i.imgur.com/etlzzME.jpg

Za to w przypadku normalnego już nie. Przy odczytaniu licznik_limit w funkcji main wynosi 0, mimo że bezpośredni cout po metodzie wskazuje że "dodano liczbę do limitu".
http://i.imgur.com/dU5dRQf.jpg

Moje kody (dam jako linki, bo trochę tego jest). Jakby co to sprawdzanie salda ma być w bankomacie normalnym, ale dla testów dałem do podstawowego na screenach czy "działa jak należy"... no i nie działa.
podstawowy.h - http://pastebin.com/7vTqVgLS
podstawowy.cpp - http://pastebin.com/aLw2Pbhq
normalny.h - http://pastebin.com/4p9icX14
normalny.cpp - http://pastebin.com/uzdbejhZ


Naprawdę bardzo prosiłbym o pomoc, bo to już przerasta moje możliwości.
P-119837
Atexor
Temat założony przez niniejszego użytkownika
» 2014-11-10 22:06:34
Problem rozwiązałem przy użyciu klasy, która ma służyć tylko do przechowywania zmiennej "saldo" oraz zmiennych statycznych (dziękuję Monika90 za radę :)).
Temat można zamknąć, zaś dla szukających rozwiązania tego typu problemy zamieszczę przykładowy kod:

main.cpp
C/C++
#include <iostream>
#include "A.h"
#include "B.h"
#include "Cd.h"

using namespace std;

int main()
{
    A konto_a;
    B konto_b;
    Cd konto_cd;
   
    konto_cd.wypisz_saldo( 50 );
    konto_cd.zmien_saldo( 50 ); //tu sie pokaze, ze zmieniono saldo w metodzie klasy b
    konto_b.zmien_saldo( 50 );
    konto_cd.wypisz_saldo( 50 );
    //couty w komentarzach dla testu, dzialaja dla salda publicznego
    //cout<<"Sprawdzenie kwoty: w obiekcie konto_a: "<<konto_a.saldo<<endl;
    konto_cd.zmien_saldo( 50 );
    //cout<<"Sprawdzenie kwoty: w klasie A: "<<A::saldo<<endl;
    konto_b.zmien_saldo( 50 );
    //cout<<"Sprawdzenie kwoty: w klasie A: "<<A::saldo<<endl;
    konto_cd.wypisz_saldo( 50 );
    konto_b.zmien_saldo( 50 );
    //cout<<"Sprawdzenie kwoty: w obiekcie konto_a: "<<konto_a.saldo<<endl;
    system( "PAUSE" );
    return 0;
}


A.h
C/C++
#pragma once
#include <iostream>
using namespace std;

class A
{
protected:
    static int saldo;
};

A.cpp
C/C++
#include "A.h"

int A::saldo = 1000;

B.h
C/C++
#pragma once
#include <iostream>
#include "A.h"

using namespace std;

class B
    : public A
{
public:
    static const int saldo;
    void zmien_saldo( int x );
    B( void );
    ~B( void );
};

B.cpp
C/C++
#include "B.h"


B::B( void )
{
}
B::~B( void )
{
}

void B::zmien_saldo( int x )
{
    A::saldo -= x;
    cout << "W metodzie b zmien_saldo wyplacono " << x << ", teraz saldo wynosi:" << A::saldo << endl;
}

Cd.h //taka nazwa, bo nie moglem utworzyc klasy o nazwie C, zarezerwowana nazwa w Visualu
C/C++
#pragma once
#include "B.h"

class Cd
    : public B
{
public:
    static int saldo;
    void wypisz_saldo( int x );
    Cd( void );
    ~Cd( void );
};

Cd.cpp
C/C++
#include "Cd.h"

Cd::Cd( void )
{
}
Cd::~Cd( void )
{
}

void Cd::wypisz_saldo( int x )
{
    cout << "Pokazano saldo w metodzie w Cd.cpp " << A::saldo << endl;
}
P-120344
« 1 »
  Strona 1 z 1