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 |
|
Monika90 |
» 2014-11-01 16:22:43 Nie rozumiem w czym problem. Przecież to działa class B { protected: int x; };
class D : public B { public: void f() { x = 9; } };
Inna sprawa że dane z dostępem protected to zły pomysł. |
|
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): class A { public: int zmienna; };
class B : public A { };
Klasa B przyjmuje zmienną=25 z klasy A. W funkcji głównej programu main np. zrobimy: 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". |
|
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. |
|
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ć... |
|
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/7vTqVgLSpodstawowy.cpp - http://pastebin.com/aLw2Pbhqnormalny.h - http://pastebin.com/4p9icX14normalny.cpp - http://pastebin.com/uzdbejhZNaprawdę bardzo prosiłbym o pomoc, bo to już przerasta moje możliwości. |
|
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 #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 ); konto_b.zmien_saldo( 50 ); konto_cd.wypisz_saldo( 50 ); konto_cd.zmien_saldo( 50 ); konto_b.zmien_saldo( 50 ); konto_cd.wypisz_saldo( 50 ); konto_b.zmien_saldo( 50 ); system( "PAUSE" ); return 0; }
A.h #pragma once #include <iostream> using namespace std;
class A { protected: static int saldo; };
A.cpp #include "A.h"
int A::saldo = 1000;
B.h #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 #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 #pragma once #include "B.h"
class Cd : public B { public: static int saldo; void wypisz_saldo( int x ); Cd( void ); ~Cd( void ); };
Cd.cpp #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; }
|
|
« 1 » |