Friend-Klasse will nicht ganz funktionieren
-
Hallo Leute,
ich wollte gerade die "friend" Eigenschaft ausprobieren und mir eine Friend-Klasse basteln...
Ich habe eine Klasse Auto und eine Klasse Service,
jetzt soll die Klasse Service auf das Atribut kmStand von Klasse Auto zugreifen können welches private ist.
Das bedeutet Klasse Service muss eine friend-Klasse von Auto sein...So sehe meine Header-Files aus:
#ifndef AUTO_H #define AUTO_H class Auto { friend class Service; public: Auto(); Auto(double newVerbrauch, double newTankFuellung, int newKmStand = 0); ~Auto(); double getVerbrauch() const; double getFuellung() const; int getKmStand() const; bool tanke(double liter); bool fahre(int km); private: double verbrauch; double maxTankFuellung; double tankFuellung; int kmStand; }; #endif /* AUTO_H */#ifndef SERVICE_H #define SERVICE_H #include "Auto.h" class Service { public: Service(); ~Service(); int getKmStandAuto(Auto& a); private: }; #endif /* SERVICE_H */Doch leider will das ganze nicht funktionieren sobald ich mein Programm laufen lasse erhalte ich eine Fehlermeldung:
"/usr/bin/make" -f nbproject/Makefile-Debug.mk QMAKE= SUBPROJECTS= .build-conf "/usr/bin/make" -f nbproject/Makefile-Debug.mk dist/Debug/GNU-MacOSX/aufgabe_1 mkdir -p build/Debug/GNU-MacOSX rm -f build/Debug/GNU-MacOSX/Service.o.d g++ -c -g -MMD -MP -MF build/Debug/GNU-MacOSX/Service.o.d -o build/Debug/GNU-MacOSX/Service.o Service.cpp Auto.h: In function 'int getKmStandAuto(Auto&)': Auto.h:21: error: 'int Auto::kmStand' is private Service.cpp:11: error: within this context make[2]: *** [build/Debug/GNU-MacOSX/Service.o] Error 1 make[1]: *** [.build-conf] Error 2 make: *** [.build-impl] Error 2 BUILD FAILED (exit value 2, total time: 111ms)Also scheint das mit der der friend Eigenschaft nicht so ganz zu funktionieren, was genau mache ich den falsch?
-
Geht bei mir: http://ideone.com/d1xhq
Meins ist ja das Selbe wie deins, nur verkürzt...
Nebenbei:
- Kapselung
friendnur auf die eine Methode - Konstante Referenz da das Auto beim Auslesen nicht verändert wird
- Konstante Methode da der Service beim Auslesen nicht verändert wird
Gruss
- Kapselung
-
Wenn ich alles in ein File schreibe, dann funktioniert es bei mir auch...
Aber wenn ich es mit Header-Files aufsplitte dann funktioniert es irgendwie nicht mehr...Das mit der Kapselung usw. ist mir klar (:
Ich will erst mal dass das funktioniert... ):
-
Dann wird es wahrscheinlich daran liegen, dass die Deklarationen/Definitionen nicht in der korrekten Reihenfolge sind (obwohl ich mir das zusammen mit dieser Fehlermeldung von deinem Compiler nicht wirklich vorstellen kann).
Korrekte Reihenfolge in dem Fall:- Klassendeklarationen
- Klassendefinitionen (wenn du
friendauf eine Methode machst spielt es hier eine Rolle, welche Klasse zuerst kommt) - Funktionsdefinitionen
Ist dies durch deine Implementierung gewährleistet?
EDIT: Was mir erst jetzt auffällt ist, dass
Autoeinepublic-Methode hat um auf die zurückgelegten Kilometer zurückzugreifen. Wieso ruft Service nicht diese auf?
-
vandread schrieb:
Wenn ich alles in ein File schreibe, dann funktioniert es bei mir auch...
Aber wenn ich es mit Header-Files aufsplitte dann funktioniert es irgendwie nicht mehr...Das mit der Kapselung usw. ist mir klar (:
Ich will erst mal dass das funktioniert... ):Vermutung: du hast das Service:: vergessen.
-
Service:: ???
Wo soll das den hin?
Dachte den Scope-Operator braucht man nur bei Namespaces...? Oo
-
Bei der Funktionsdefinition wenn sie ausserhalb der Klassendefinition ist (sieh es dir in meinen Code im obigen Post an).
-
So jetzt blick ich gar nicht mehr durch...
In deinem Beispiel arbeitest du doch mit einer friend-Funktion, ich will aber eine friend-Klasse und ich verstehe nicht wo ich da einen scope-Operator anwenden soll...Ja ich weiß dass ich diese methode nutzen könnte, das wäre mir ja persönlich auch viel lieber, aber ich soll das leider so lösen weil das so auf dem Aufgabenblatt steht (:
Hier jetzt einfach mal der komplette Code...
main.cpp
#include <cstdlib> #include <iostream> #include "Auto.h" #include "Service.h" using namespace std; int main(int argc, char** argv) { Auto aAuto(3., 50., 20000); Service s; cout << s.getKmStandAuto(aAuto); return 0; }Auto.h
#ifndef AUTO_H #define AUTO_H class Auto { friend class Service; public: Auto(); Auto(double newVerbrauch, double newTankFuellung, int newKmStand = 0); ~Auto(); double getVerbrauch() const; double getFuellung() const; int getKmStand() const; bool tanke(double liter); bool fahre(int km); private: double verbrauch; double maxTankFuellung; double tankFuellung; int kmStand; }; #endif /* AUTO_H */Auto.cpp
#include "Auto.h" Auto::Auto() :verbrauch(0.), maxTankFuellung(50.), tankFuellung(0.), kmStand(0) { } Auto::Auto(double newVerbrauch, double newTankFuellung, int newKmStand) :verbrauch(newVerbrauch), maxTankFuellung(50.), tankFuellung(newTankFuellung), kmStand(newKmStand) { } Auto::~Auto() { } double Auto::getVerbrauch() const { return verbrauch; } double Auto::getFuellung() const { return tankFuellung; } int Auto::getKmStand() const { return kmStand; } bool Auto::tanke(double liter) { if (tankFuellung + liter > maxTankFuellung) { return false; } else { tankFuellung = tankFuellung + liter; return true; } } bool Auto::fahre(int km) { if (km * (verbrauch / 100) > tankFuellung) { return false; } else { tankFuellung = tankFuellung - (km * (verbrauch / 100)); kmStand = kmStand + km; return true; } }Service.h
#ifndef SERVICE_H #define SERVICE_H #include "Auto.h" class Service { public: Service(); ~Service(); int getKmStandAuto(Auto& a); private: }; #endif /* SERVICE_H */Service.cpp
#include "Service.h" Service::Service() { } Service::~Service() { } int getKmStandAuto(Auto& a) { return a.kmStand; }Ich möchte ja nur das die Klasse Service zugriff auf alle Atribute von Auto hat ohne das Klassen-Interface von Auto zu nutzen, also ohne get-methoden...
Im Internet finde ich auch nur Beispiele wo das alles in einer C-File gemacht wird, so wie bei deinem Beispiel...
Wenn ich das so mache funktioniert das ja bei mir auch, aber wie soll das den gehen wenn man das mit header-files macht...
-
Da haben wir's!
Zuerst inkludierst du"Auto.h"und ohne der Kenntnis über das Vorhandensein der KlasseServicewillst du ihr den Zugriff auf die KlasseAutoerlauben.Lösung: Klassendeklaration (wie in meinem Code
)
-
Omg... ich hab den Fehler gefunden... Tut mir leid... es muss natürlich so aussehen:
int Service::getKmStandAuto(Auto& a) { return a.kmStand; }Ich glaub ich brauch jetzt eine Pause...
---
Edit:Also ich hab jetzt einfach das abgeändert und so funktioniert es :S
-
vandread schrieb:
Edit:
Also ich hab jetzt einfach das abgeändert und so funktioniert es :S
Das auch, hab ich übersehen, entschuldige