C++ Friend-Funktion

Hey Leute, habe ein Problem, ich habe folgendende 2 Klassen:

classHeld.h
Code:
#ifndef CLASSHELD_H_INCLUDED
#define CLASSHELD_H_INCLUDED
#include <string>
#include "classInventar.h"
#include "classItems.h"
#include <boost/smart_ptr/shared_ptr.hpp>
#include <fstream>
typedef boost::shared_ptr<Item> bPtr;
class Held
{
    public:
        Held( std::string name );
        Held( std::string name, int schnelligkeit, int staerke, int zauberfaehigkeit, int gesundheit, int ruestung, int level, int spielfortschritt, int exp, int typ );
        ~Held();
        std::string getName() const { return itsName; }
        void setName( std::string name );
        int getSchnelligkeit() const { return itsSchnelligkeit; }
        void setSchnelligkeit( int schnelligkeit );
        int getStaerke() const { return itsStaerke; }
        void setStaerke( int staerke );
        int getZauberfaehigkeit() const { return itsZauberfaehigkeit; }
        void setZauberfaehigkeit( int zauberfaehigkeit );
        int getGesundheit() const { return itsGesundheit; }
        void setGesundheit( int gesundheit );
        int getRuestung() const { return itsRuestung; }
        void setRuestung( int ruestung);
        int getLevel() const { return itsLevel;}
        void setLevel( int level );
        int getSpielfortschritt() const { return itsSpielfortschritt; }
        void setSpielfortschritt( int spielfortschritt );
        int getEXP() const { return itsEXP; }
        void setEXP( int exp );
        int getTyp() const { return itsTyp; }
        void setTyp( int typ );
        void showAttributes() const;
        void checkLevel();
        void showInventar();
        void addItem( bPtr Item );
        void checkItemLoeschen();
        bool checkItemWaffe( int&, int&, std::string& );
        bool checkItemRuestung( int&, int&, std::string& );
        bool checkItemWaffeZauber( int&, int&, std::string& );
        void writeInventar( std::ofstream );
        void loadInventar( std::ifstream, Held*, bPtr& );
    private:
        std::string itsName;
        int itsSchnelligkeit;
        int itsStaerke;
        int itsZauberfaehigkeit;
        int itsGesundheit;
        int itsRuestung;
        int itsLevel;
        int itsSpielfortschritt;
        int itsEXP;
        int itsTyp;
        Inventar itsInventar;
};

#endif // CLASSHELD_H_INCLUDED

classInventar.h
Code:
#ifndef CLASSINVENTAR_H_INCLUDED
#define CLASSINVENTAR_H_INCLUDED
#include "classItems.h"
#include "classHeld.h"
#include <vector>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <fstream>
typedef boost::shared_ptr<Item> bPtr;
class Inventar
{
    public:
        void itemHinzufuegen( bPtr theItem );
        void itemLoeschen();
        void showAll();
        bool itemCheckWaffe( int&, int&, std::string& );
        bool itemCheckRuestung( int&, int&, std::string& );
        bool itemCheckZauberWaffe( int&, int&, std::string& );
        friend void Held::writeInventar( std::ofstream );
        friend void Held::loadInventar( std::ifstream, Held* );
    private:
        std::vector< bPtr > items;
        std::vector< bPtr >::iterator theIt;
};
#endif // CLASSINVENTAR_H_INCLUDED

Und zwar bekomme ich in der Header-Datei vom Inventar die Meldung held has not been declared.

Hoffe ihr könnt mir helfen;-)
 
Versuch ne Vorwärtsdeklaration:
Code:
class held;
Vor der Inventarklasse einfügen und das sollte gehen.
 
Hey erst mal Danke für den Tip,
habe es nun gemacht, nun bekomme ich die Fehlermeldung:

error: member void Held::writeInventar( std::ofstream ) declared as friend before type Held defined.
Das ganze gibts dann auch noch für die zweite friend funktion load Inventar.

Hoffe dass hilft jetzt vll zur Fehlersuche weiter;-)
 
Ja, der Fehler liegt darin, dass er zum Zeitpunkt der Defintion von Inventar nun zwar weiß, dass später noch eine Klasse vom Typ Held kommen wird, aber noch keine Ahnung über deren Aussehen hat. So wie du das lösen möchtest, wird das also nicht wirklich möglich sein.
Eine mögliche Lösung wäre eine eigene Funktion in Inventar, die dann das ausführt, dass Held machen möchte. Damit würdest du außerdem die Kapselung nicht aufbrechen.

mfg benediktibk
 
Hey ok dankeschön.
Ich habe das bei mehreren Funktionen in meinem Projekt ja auch schon genau so gelöst wie du sagst, weiß selber net warum ichs bei der Funktion so machen wollte:wink:

Werde es jetzt mal so versuchen=)

Danke auf jeden Fall

Jetzt hab ich trotzdem ein Problem, wenn ich eine extra Funktion in Inventar mache welche aus Held aufgerufen wird, gehts trotzdem net=(
Denn dann muss Inventar einen Parameter der einen Zeiger auf Held ist übernehmen, und dann sagt er mir wieder Held has not been declared=(
 
Zuletzt bearbeitet:
Benötigt die Funktion wirklich den gesamten Helden, oder reichen ein paar Variablen? Eventuell kann man sich auf ein paar Parameter beschränken?

mfg benediktibk
 
Ja also die Funktion von Inventar, muss die Funktion addItem vom Held ausführen.
Da ich ja mit einem Held die Funktion aufrufe, welche dann die Funktion vom Inventar aufruft, kann ich dann vll in der Funktion vom Inventar mit dem this Zeiger die Funktion addItem auführen, oder funktioniert das nicht?
Sonst wüsste ich keine Möglichkeit=(


Jetzt versteh ich gar nix mehr....:(
Hab jetzt das ganze nochmal so probiert wie zuvor, erst mal in classInventar.h vor die Klassendefinition ne Vorwärtsdeklaration class Held, und hab dann wieder als Funktionsparamter einen Zeiger auf Held gemacht, und hab dann in der Funktion von Held, welche die Funktion vom Inventar aufruft, einfach den this Zeiger übergeben, ist ja ein zeiger auf held. Das compiliert er mir.
Jetzt bekomme ich aber noch die Fehlermeldung in classHeld.h Inventar does not name a typ.
Versteh ich jetzt echt nicht, ich include dort doch die classInventar.h

Hoffe jemand kann mir helfen=)
 
Zuletzt bearbeitet:
So hier ist mal alles was ich denke was man benötigt, ist zwar bisschen viel, aber ich hoffe es hilft;-)
Vielleicht läuft dann endlich alles=)
class Invenar.h
Code:
#ifndef CLASSINVENTAR_H_INCLUDED
#define CLASSINVENTAR_H_INCLUDED
#include "classItems.h"
#include "classHeld.h"
#include <vector>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <fstream>
#include <string>
typedef boost::shared_ptr<Item> bPtr;
class Held;
class Inventar
{
    public:
        void itemHinzufuegen( bPtr theItem );
        void itemLoeschen();
        void showAll();
        bool itemCheckWaffe( int&, int&, std::string& );
        bool itemCheckRuestung( int&, int&, std::string& );
        bool itemCheckZauberWaffe( int&, int&, std::string& );
        void writeOutInventar( std::ofstream& );
        void loadInInventar( std::ifstream&, Held*, bPtr* );
    private:
        std::vector< bPtr > items;
        std::vector< bPtr >::iterator theIt;
};
#endif // CLASSINVENTAR_H_INCLUDED

class Invenar.cpp
Code:
// nur die 3 Funktionen um die es geht bzw eg nur die Load funktion und additem
void Inventar::itemHinzufuegen( bPtr theItem )
{
    if( theItem->getItemTyp() == WAFFE )
    {
        theIt = items.begin();
        while( theIt != items.end() )
        {
            if( ( *theIt )->getItemTyp() == WAFFE )
            {
                this->showAll();
                cout << "Moechtest du die gefundene Waffe mir der Waffe aus deinem Inventar ersetzen(1) oder nicht(2 und alles andere): ";
                int auswahl;
                cin >> auswahl;
                if( auswahl == 1 )
                {
                    for( theIt = items.begin(); theIt != items.end(); )
                    {
                        if( ( *theIt )->getItemTyp() == WAFFE )
                        {
                            items.erase( theIt );
                            cout << "\n" << ( *theIt )->getName() << " wurde gelöscht\n";
                        }
                        else
                            ++theIt;
                    }
                    items.push_back( theItem );
                    cout << "Item wurde aufgenommen!\n";
                }
                else
                    cout << "Item wurde nicht aufgenommen!\n";
                break;
            }
            ++theIt;
        }
    }
    else if( theItem->getItemTyp() == RUESTUNG )
    {
        theIt = items.begin();
        while( theIt != items.end() )
        {
            if( ( *theIt )->getItemTyp() == RUESTUNG )
            {
                this->showAll();
                cout << "Moechtest du die gefundene Ruestung mir der Ruestung aus deinem Inventar ersetzen(1) oder nicht(2 und alles andere): ";
                int auswahl;
                cin >> auswahl;
                if( auswahl == 1 )
                {
                    for( theIt = items.begin(); theIt != items.end(); )
                    {
                        if( ( *theIt )->getItemTyp() == RUESTUNG )
                        {
                            items.erase( theIt );
                            cout << "\n" << ( *theIt )->getName() << " wurde gelöscht\n";
                        }
                        else
                            ++theIt;
                    }
                    items.push_back( theItem );
                    cout << "Item wurde aufgenommen!\n";
                }
                else
                    cout << "Item wurde nicht aufgenommen!\n";
                break;
            }
            ++theIt;
        }
    }
    else if( theItem->getItemTyp() == ZAUBERWAFFE )
    {
        theIt = items.begin();
        while( theIt != items.end() )
        {
            if( ( *theIt )->getItemTyp() == ZAUBERWAFFE )
            {
                this->showAll();
                cout << "Moechtest du die gefundene Zauberwaffe mir der Zauberwaffe aus deinem Inventar ersetzen(1) oder nicht(2 und alles andere): ";
                int auswahl;
                cin >> auswahl;
                if( auswahl == 1 )
                {
                    for( theIt = items.begin(); theIt != items.end(); )
                    {
                        if( ( *theIt )->getItemTyp() == ZAUBERWAFFE )
                        {
                            items.erase( theIt );
                            cout << "\n" << ( *theIt )->getName() << " wurde gelöscht\n";
                        }
                        else
                            ++theIt;
                    }
                    items.push_back( theItem );
                    cout << "Item wurde aufgenommen!\n";
                }
                else
                    cout << "Item wurde nicht aufgenommen!\n";
                break;
            }
            ++theIt;
        }
    }
}
void Inventar::itemLoeschen()
{
    for( theIt = items.begin(); theIt != items.end(); )
    {
        if( ( *theIt )->getVerfuegbarkeit() == 0 )
        {
            items.erase( theIt );
            cout << "\n" << ( *theIt )->getName() << " wurde gelöscht\n";
        }
        else
            ++theIt;
    }
}
void Inventar::writeOutInventar( ofstream& fout )
{
    int a;
    int b;
    string name;
    for( theIt = items.begin(); theIt != items.end(); ++theIt )
    {
        if( itsInventar.itemCheckWaffe( a, b, name ) )
        {
            fout << name << endl;
            fout << ( *theIt )->getItemTyp() << endl;
            fout << a << endl;
            fout << b << endl;
            fout << ( *theIt )->getVerfuegbarkeit() << "\n\n";
        }
        else if( itsInventar.itemCheckZauberWaffe( a, b, name ) )
        {
            fout << name << endl;
            fout << ( *theIt )->getItemTyp() << endl;
            fout << a << endl;
            fout << b << endl;
            fout << ( *theIt )->getVerfuegbarkeit() << "\n\n";
        }
        else if( itsInventar.itemCheckRuestung( a, b, name ) )
        {
            fout << name << endl;
            fout << ( *theIt )->getItemTyp() << endl;
            fout << a << endl;
            fout << b << endl;
            fout << ( *theIt )->getVerfuegbarkeit() << "\n\n";
        }
    }
}
void Inventar::loadInInventar( ifstream& fin, Held* spieler, bPtr array[] )
{
    string name;
    int typ;
    int wert;
    int schnelligkeit;
    int verfuegbarkeit;

    getline( fin, name );
    fin >> typ;
    while( true )
    {
        if( fin.peek() == '\n' )
            break;
    }
    if( typ == WAFFE )
    {
        fin >> wert;
        while( true )
        {
            if( fin.peek() == '\n' )
                break;
        }
        fin >> schnelligkeit;
        while( true )
        {
            if( fin.peek() == '\n' )
                break;
        }
        fin >> verfuegbarkeit;
        for( int i = 0; i < 2; ++i )
        {
            if( ( array[i]->getItemTyp() == typ ) && ( array[i]->getSchaden() == wert ) && ( array[i]->getSchnelligkeit() == schnelligkeit ) )
                spieler->addItem( array[i] );
        }
    }
    else if( typ == RUESTUNG )
    {
        fin >> wert;
        while( true )
        {
            if( fin.peek() == '\n' )
                break;
        }
        fin >> schnelligkeit;
        while( true )
        {
            if( fin.peek() == '\n' )
                break;
        }
        fin >> verfuegbarkeit;
         for( int i = 0; i < 2; ++i )
        {
            if( ( array[i]->getItemTyp() == typ ) && ( array[i]->getRuestung() == wert ) && ( array[i]->getSchnelligkeit() == schnelligkeit ) )
                spieler->addItem( array[i] );
        }
    }
    else if( typ == ZAUBERWAFFE )
    {
        fin >> wert;
        while( true )
        {
            if( fin.peek() == '\n' )
                break;
        }
        fin >> schnelligkeit;
        while( true )
        {
            if( fin.peek() == '\n' )
                break;
        }
        fin >> verfuegbarkeit;
         for( int i = 0; i < 2; ++i )
        {
            if( ( array[i]->getItemTyp() == typ ) && ( array[i]->getZauberfaehigkeit() == wert ) && ( array[i]->getSchnelligkeit() == schnelligkeit ) )
                spieler->addItem( array[i] );
        }
    }
}

classHeld.h
Code:
#ifndef CLASSHELD_H_INCLUDED
#define CLASSHELD_H_INCLUDED
#include <string>
#include "classInventar.h"
#include "classItems.h"
#include <boost/smart_ptr/shared_ptr.hpp>
#include <fstream>
typedef boost::shared_ptr<Item> bPtr;
class Held
{
    public:
        Held( std::string name );
        Held( std::string name, int schnelligkeit, int staerke, int zauberfaehigkeit, int gesundheit, int ruestung, int level, int spielfortschritt, int exp, int typ );
        ~Held();
        std::string getName() const { return itsName; }
        void setName( std::string name );
        int getSchnelligkeit() const { return itsSchnelligkeit; }
        void setSchnelligkeit( int schnelligkeit );
        int getStaerke() const { return itsStaerke; }
        void setStaerke( int staerke );
        int getZauberfaehigkeit() const { return itsZauberfaehigkeit; }
        void setZauberfaehigkeit( int zauberfaehigkeit );
        int getGesundheit() const { return itsGesundheit; }
        void setGesundheit( int gesundheit );
        int getRuestung() const { return itsRuestung; }
        void setRuestung( int ruestung);
        int getLevel() const { return itsLevel;}
        void setLevel( int level );
        int getSpielfortschritt() const { return itsSpielfortschritt; }
        void setSpielfortschritt( int spielfortschritt );
        int getEXP() const { return itsEXP; }
        void setEXP( int exp );
        int getTyp() const { return itsTyp; }
        void setTyp( int typ );
        void showAttributes() const;
        void checkLevel();
        void showInventar();
        void addItem( bPtr Item );
        void checkItemLoeschen();
        bool checkItemWaffe( int&, int&, std::string& );
        bool checkItemRuestung( int&, int&, std::string& );
        bool checkItemWaffeZauber( int&, int&, std::string& );
        void writeInventar( std::ofstream& );
        void loadInventar( std::ifstream&, bPtr* );
    private:
        std::string itsName;
        int itsSchnelligkeit;
        int itsStaerke;
        int itsZauberfaehigkeit;
        int itsGesundheit;
        int itsRuestung;
        int itsLevel;
        int itsSpielfortschritt;
        int itsEXP;
        int itsTyp;
        Inventar itsInventar;
};
#endif // CLASSHELD_H_INCLUDED

classHeld.cpp
Code:
// wieder die 3 Funktionen
void Held::addItem( bPtr theItem )
{
    itsInventar.itemHinzufuegen( theItem );
}
void Held::writeInventar( ofstream& fout )
{
    itsInventar.writeOutInventar( fout );
}
void Held::loadInventar( ifstream& fin, bPtr array[] )
{
    itsInventar.loadInInventar( fin, this, array );
}

classItems.h
Code:
#ifndef CLASSITEMS_H_INCLUDED
#define CLASSITEMS_H_INCLUDED
#include <string>
enum ItemTyp
{
    WAFFE,
    ZAUBERWAFFE,
    RUESTUNG,
    TRANK
};
class Item
{
    public:
        Item( ItemTyp typ, int verfuegbarkeit, std::string name );
        virtual ~Item();
        virtual ItemTyp getItemTyp() const { return itsTyp; }
        virtual int getVerfuegbarkeit() const { return itsVerfuegbarkeit; }
        virtual std::string getName() const { return itsName; }
        virtual int getSchaden() const = 0; // Hier schon deklariert, damit ich im Inventar allgemeint Items speichern kann, sonst fehlen die Funktionen da Zeiger auf Item
        virtual int getSchnelligkeit() const = 0;
        virtual int getRuestung() const = 0;
        virtual int getGesundheit() const = 0;
        virtual int getZauberfaehigkeit() const = 0;
    private:
        ItemTyp itsTyp;
        int itsVerfuegbarkeit;
        std::string itsName;
};
class WaffenItem : public Item
{
    public:
        WaffenItem( int verfuegbarkeit, int schaden, int schnelligkeit, std::string name );
        ~WaffenItem();
        int getSchaden() const { return itsSchaden; }
        int getSchnelligkeit() const { return itsSchnelligkeit; }
    private:
        int itsSchaden;
        int itsSchnelligkeit;
};
class Schwert : public WaffenItem
{
    public:
        Schwert( int verfuegbarkeit );
        ~Schwert();
};
class Messer : public WaffenItem
{
    public:
        Messer( int verfuegbarkeit );
        ~Messer();
};
class RuestungsItem : public Item
{
    public:
        RuestungsItem( int verfuegbarkeit, int ruestung, int schnelligkeit, std::string name );
        ~RuestungsItem();
        int getRuestung() const { return itsRuestung; }
        int getSchnelligkeit() const { return itsSchnelligkeit; }
    private:
        int itsRuestung;
        int itsSchnelligkeit;
};
class Kopfschutz : public RuestungsItem
{
    public:
        Kopfschutz( int verfuegbarkeit );
        ~Kopfschutz();
};
class TrankItem : public Item
{
    public:
        TrankItem( int verfuegbarkeit, int gesundheit, std::string name );
        ~TrankItem();
        int getGesundheit() const { return itsGesundheit; }
    private:
        int itsGesundheit;
};
class HeilTrank20 : public TrankItem
{
    public:
        HeilTrank20( int verfuegbarkeit );
        ~HeilTrank20();
};
class ZauberItem : public Item
{
    public:
        ZauberItem( int verfuegbarkeit, int zauberfaehigkeit, std::string name );
        ~ZauberItem();
        int getZauberfaehigkeit() const { return itsZauberfaehigkeit; }
    private:
        int itsZauberfaehigkeit;
};
class Zauberverstaerker3 : public ZauberItem
{
    public:
        Zauberverstaerker3( int verfuegbarkeit );
        ~Zauberverstaerker3();
};
#endif // CLASSITEMS_H_INCLUDED

classItems.cpp
Code:
#include "classItems.h"
#include <string>
using namespace std;
Item::Item( ItemTyp typ, int verfuegbarkeit, string name ):
    itsTyp( typ ), itsVerfuegbarkeit( verfuegbarkeit ), itsName( name )
{
}
Item::~Item()
{
}
WaffenItem::WaffenItem( int verfuegbarkeit, int schaden, int schnelligkeit, string name ):
    Item( WAFFE, verfuegbarkeit, name ), itsSchaden( schaden ), itsSchnelligkeit( schnelligkeit )
{
}
WaffenItem::~WaffenItem()
{
}
Schwert::Schwert( int verfuegbarkeit ):
    WaffenItem( verfuegbarkeit, 5, 2, "Schwert" )
{
}
Schwert::~Schwert()
{
}
Messer::Messer( int verfuegbarkeit ):
    WaffenItem( verfuegbarkeit, 3, 3, "Messer" )
{
}
Messer::~Messer()
{
}
RuestungsItem::RuestungsItem( int verfuegbarkeit, int ruestung, int schnelligkeit, string name ):
    Item( RUESTUNG, verfuegbarkeit, name ), itsRuestung( ruestung ), itsSchnelligkeit( schnelligkeit )
{
}
RuestungsItem::~RuestungsItem()
{
}
Kopfschutz::Kopfschutz( int verfuegbarkeit ):
    RuestungsItem( verfuegbarkeit, 3, 2, "Kopfschutz" )
{
}
Kopfschutz::~Kopfschutz()
{
}
TrankItem::TrankItem( int verfuegbarkeit, int gesundheit, string name ):
    Item( TRANK, verfuegbarkeit, name ), itsGesundheit( gesundheit )
{
}
TrankItem::~TrankItem()
{
}
HeilTrank20::HeilTrank20( int verfuegbarkeit ):
    TrankItem( verfuegbarkeit, 20, "Heil-Trank-20" )
{
}
HeilTrank20::~HeilTrank20()
{
}
ZauberItem::ZauberItem( int verfuegbarkeit, int zauberfaehigkeit, string name ):
    Item( ZAUBERWAFFE, verfuegbarkeit, name ), itsZauberfaehigkeit( zauberfaehigkeit )
{
}
ZauberItem::~ZauberItem()
{
}
Zauberverstaerker3::Zauberverstaerker3( int verfuegbarkeit ):
    ZauberItem( verfuegbarkeit, 3, "Zauberverstaerker3" )
{
}
Zauberverstaerker3::~Zauberverstaerker3()
{
}
 
Ich behaupte jetzt nicht alles durchgelesen zu haben, aber so müsste es funktionieren:
Code:
void Inventar::loadInInventar( ifstream& fin, Inventar &itsInventar, bPtr array[] )
{
       ...
       itsInventar.itemHinzufuegen(Item);
       ...
}
mfg benediktibk
 
Hey,
also ich hab des jetzt bei der writeout-Funktion so gemacht, mit der Übergabe einer Referenz auf Inventar.
Jetzt kompiliert er alles ohne Fehler, bis auf in classHeld.h, sagt er Inventar has not been declared, dann hab ich eine Vorwärtsdeklaration gemacht, jetzt sagt er mir field itsInventar has incomplite type.

Was soll ich denn jetzt machen, ich verstehe dass net ich nutz doch einfach nur Einbettung...

Danke schonmal
 
Entferne aus der Inventar.h die Vorwärtsdeklaration auf Held und die Inkludierung von Held.h. Umgekehrt muss aber in Held.h die Inventar.h inkludiert sein. Dann benötigtst du vor dem Helden auch keine Vorwärtsdeklaration vom Inventar mehr.

mfg benediktibk
 
Hey danke, habs so gemacht und noch einige viele andere Änderungen, jetzt klappt es eg so weit mal, sind nur noch ein paar andere Fehler:-P
Ich hoffe das klappt:D:D
Auf jeden Fall danke für deien Mühe;-)

Es klappt jetzt beim compilieren alles, blos beim linken bekomme ich viele Fehler und zwar sagt er mir:

in function '_ZNK10WaffenItem16getSchnelligkeitEv'
undefined reference to Item::getSchaden()const
so zeigt er mir mit undefined reference to alle get-Funktionen vom item und alle mehrmals, ingesamt 36 errors.

Weiß nicht was ich damit anfangen soll, hab Klasse Item wie oben gepostet blos nicht mehr abstrakt also ohne =0, denn da bekam ich nur Fehler mit:D

Hoffe ihr könnt mir irgendwie helfen,
vielen Dank schonmal
 
Zuletzt bearbeitet:
Ich rate jetzt einfach mal, es gibt nirgends folgendes:
Code:
int Item::getSchaden() const
{
    ...
}
Das würde ich aus dem Fehler schließen. Um diesen Fehler zu beheben, musst du in der Basisklasse Item eine Implementierung von getSchaden anbieten. Mit einer reinen virtuellen Funktionen (virtual ... = 0) würdest du aussagen, dass du keine Standardimplementierung vorsiehst (ist jetzt nicht ganz korrekt, bitte haut mich deswegen nicht :) ). Das hätte aber den Nach- bzw. Vorteil, dass du die Funktion in allen Klassen, die von Item erben, implementieren musst, um sie instanziieren zu können. Also, entweder du bastelst dir eine Standardimplementierung, oder du implementierst sie in jeder Ableitung.

mfg benediktibk

PS: Bitte verwende in längeren CODE-Abschnitten einen Spoiler (im Editor unter "SPOIL"). Ich ärgere mich jedes Mal beim Scrollen :wink:
 
Zuletzt bearbeitet:
Erst mal danke,
also ich habe in den abgeleiteten Klassen, die Funktionen schon implementiert, blos inline...macht das was?
Hier mal einfach die Item klasse in nem spoiler;-)
classItems.h
Code:
#ifndef CLASSITEMS_H_INCLUDED
#define CLASSITEMS_H_INCLUDED
#include <string>
enum ItemTyp
{
    WAFFE,
    ZAUBERWAFFE,
    RUESTUNG,
    TRANK
};
class Item
{
    public:
        Item( ItemTyp typ, int verfuegbarkeit, std::string name );
        virtual ~Item();
        virtual ItemTyp getItemTyp() const { return itsTyp; }
        virtual int getVerfuegbarkeit() const { return itsVerfuegbarkeit; }
        virtual std::string getName() const { return itsName; }
        virtual int getSchaden() const; // Hier schon deklariert, damit ich im Inventar allgemeint Items speichern kann, sonst fehlen die Funktionen da Zeiger auf Item
        virtual int getSchnelligkeit() const;
        virtual int getRuestung() const;
        virtual int getGesundheit() const;
        virtual int getZauberfaehigkeit() const;
    private:
        ItemTyp itsTyp;
        int itsVerfuegbarkeit;
        std::string itsName;
};
class WaffenItem : public Item
{
    public:
        WaffenItem( int verfuegbarkeit, int schaden, int schnelligkeit, std::string name );
        ~WaffenItem();
        int getSchaden() const { return itsSchaden; }
        int getSchnelligkeit() const { return itsSchnelligkeit; }
    private:
        int itsSchaden;
        int itsSchnelligkeit;
};
class Schwert : public WaffenItem
{
    public:
        Schwert( int verfuegbarkeit );
        ~Schwert();
};
class Messer : public WaffenItem
{
    public:
        Messer( int verfuegbarkeit );
        ~Messer();
};
class RuestungsItem : public Item
{
    public:
        RuestungsItem( int verfuegbarkeit, int ruestung, int schnelligkeit, std::string name );
        ~RuestungsItem();
        int getRuestung() const { return itsRuestung; }
        int getSchnelligkeit() const { return itsSchnelligkeit; }
    private:
        int itsRuestung;
        int itsSchnelligkeit;
};
class Kopfschutz : public RuestungsItem
{
    public:
        Kopfschutz( int verfuegbarkeit );
        ~Kopfschutz();
};
class TrankItem : public Item
{
    public:
        TrankItem( int verfuegbarkeit, int gesundheit, std::string name );
        ~TrankItem();
        int getGesundheit() const { return itsGesundheit; }
    private:
        int itsGesundheit;
};
class HeilTrank20 : public TrankItem
{
    public:
        HeilTrank20( int verfuegbarkeit );
        ~HeilTrank20();
};
class ZauberItem : public Item
{
    public:
        ZauberItem( int verfuegbarkeit, int zauberfaehigkeit, std::string name );
        ~ZauberItem();
        int getZauberfaehigkeit() const { return itsZauberfaehigkeit; }
    private:
        int itsZauberfaehigkeit;
};
class Zauberverstaerker3 : public ZauberItem
{
    public:
        Zauberverstaerker3( int verfuegbarkeit );
        ~Zauberverstaerker3();
};
#endif // CLASSITEMS_H_INCLUDED
classItems.cpp
Code:
#include "classItems.h"
#include <string>
using namespace std;
Item::Item( ItemTyp typ, int verfuegbarkeit, string name ):
    itsTyp( typ ), itsVerfuegbarkeit( verfuegbarkeit ), itsName( name )
{
}
Item::~Item()
{
}
WaffenItem::WaffenItem( int verfuegbarkeit, int schaden, int schnelligkeit, string name ):
    Item( WAFFE, verfuegbarkeit, name ), itsSchaden( schaden ), itsSchnelligkeit( schnelligkeit )
{
}
WaffenItem::~WaffenItem()
{
}
Schwert::Schwert( int verfuegbarkeit ):
    WaffenItem( verfuegbarkeit, 5, 2, "Schwert" )
{
}
Schwert::~Schwert()
{
}
Messer::Messer( int verfuegbarkeit ):
    WaffenItem( verfuegbarkeit, 3, 3, "Messer" )
{
}
Messer::~Messer()
{
}
RuestungsItem::RuestungsItem( int verfuegbarkeit, int ruestung, int schnelligkeit, string name ):
    Item( RUESTUNG, verfuegbarkeit, name ), itsRuestung( ruestung ), itsSchnelligkeit( schnelligkeit )
{
}
RuestungsItem::~RuestungsItem()
{
}
Kopfschutz::Kopfschutz( int verfuegbarkeit ):
    RuestungsItem( verfuegbarkeit, 3, 2, "Kopfschutz" )
{
}
Kopfschutz::~Kopfschutz()
{
}
TrankItem::TrankItem( int verfuegbarkeit, int gesundheit, string name ):
    Item( TRANK, verfuegbarkeit, name ), itsGesundheit( gesundheit )
{
}
TrankItem::~TrankItem()
{
}
HeilTrank20::HeilTrank20( int verfuegbarkeit ):
    TrankItem( verfuegbarkeit, 20, "Heil-Trank-20" )
{
}
HeilTrank20::~HeilTrank20()
{
}
ZauberItem::ZauberItem( int verfuegbarkeit, int zauberfaehigkeit, string name ):
    Item( ZAUBERWAFFE, verfuegbarkeit, name ), itsZauberfaehigkeit( zauberfaehigkeit )
{
}
ZauberItem::~ZauberItem()
{
}
Zauberverstaerker3::Zauberverstaerker3( int verfuegbarkeit ):
    ZauberItem( verfuegbarkeit, 3, "Zauberverstaerker3" )
{
}
Zauberverstaerker3::~Zauberverstaerker3()
{
}

So vielleicht findest du da den Fehler, ich kann auf jeden Fall nicht finden wo dran es liegen soll...=(

EDIT:
Ich glaube ich hab den Fehler, wenn ich jetzt zum Beispiel die virtuellen Funktionen in der Basisklasse Item abstrakt mache also mit = 0; dann sagt er mir in meinem Code er kann kein Objekt vom Typ Kopfschutz zuweisen, da getSchaden und die anderen Funktionen abstrakt sind.
Ich hab sie ja jedoch in den Klassen wie WaffenItem ZauberWaffenItem RuestungsItem implementiert, und diese 3 Klassen die ja von Item abgeleitet sind, hab dann wieder eben die einzelnen speziellen Klassen wie Schwert oder Kopfschutz.
Blos wie bekomme ich es jetzt hin, wenn ich jetzt zum Beispiel bei Schwert nochmal die Funktion extra hinschreiben will, sagt er mir itsSchaden is private bei WaffenItem.
Hoffe du weißt was ich mein und kannst mir helfen, oder halt jemand anderes;-)

Schonmal vielen Dank
 
Zuletzt bearbeitet:
Code:
class Item
{
    public:
        Item( ItemTyp typ, int verfuegbarkeit, std::string name );
        virtual ~Item();
        virtual ItemTyp getItemTyp() const { return itsTyp; }
        virtual int getVerfuegbarkeit() const { return itsVerfuegbarkeit; }
        virtual std::string getName() const { return itsName; }
        virtual int getSchaden() const; // Hier schon deklariert, damit ich im Inventar allgemeint Items speichern kann, sonst fehlen die Funktionen da Zeiger auf Item
        virtual int getSchnelligkeit() const;
        virtual int getRuestung() const;
        virtual int getGesundheit() const;
        virtual int getZauberfaehigkeit() const;
    private:
        ItemTyp itsTyp;
        int itsVerfuegbarkeit;
        std::string itsName;
};
getSchaden hat keinen Funktionsrumpf ( {...} )!
Für dein anderes Problem: Frage die Suchmaschine deiner Wahl nach protected.

mfg benediktibk
 
Folgendes:
Hier noch mal die Klasse wie sie jetzt ist.
classItems.h
Code:
#ifndef CLASSITEMS_H_INCLUDED
#define CLASSITEMS_H_INCLUDED
#include <string>
enum ItemTyp
{
    WAFFE,
    ZAUBERWAFFE,
    RUESTUNG,
    TRANK
};
class Item
{
    public:
        Item( ItemTyp typ, int verfuegbarkeit, std::string name );
        virtual ~Item();
        virtual ItemTyp getItemTyp() const { return itsTyp; }
        virtual int getVerfuegbarkeit() const { return itsVerfuegbarkeit; }
        virtual std::string getName() const { return itsName; }
        virtual int getSchaden() const = 0; // Hier schon deklariert, damit ich im Inventar allgemeint Items speichern kann, sonst fehlen die Funktionen da Zeiger auf Item
        virtual int getSchnelligkeit() const = 0;
        virtual int getRuestung() const = 0;
        virtual int getGesundheit() const = 0;
        virtual int getZauberfaehigkeit() const = 0;
    private:
        ItemTyp itsTyp;
        int itsVerfuegbarkeit;
        std::string itsName;
};
class WaffenItem : public Item
{
    public:
        WaffenItem( int verfuegbarkeit, int schaden, int schnelligkeit, std::string name );
        ~WaffenItem();
        int getSchaden() const { return itsSchaden; }
        int getSchnelligkeit() const { return itsSchnelligkeit; }
    protected:
        int itsSchaden;
        int itsSchnelligkeit;
};
class Schwert : public WaffenItem
{
    public:
        Schwert( int verfuegbarkeit );
        ~Schwert();
        int getSchaden() const { return itsSchaden; }
        int getSchnelligkeit() const { return itsSchnelligkeit; }
};
class Messer : public WaffenItem
{
    public:
        Messer( int verfuegbarkeit );
        ~Messer();
        int getSchaden() const { return itsSchaden; }
        int getSchnelligkeit() const { return itsSchnelligkeit; }
};
class RuestungsItem : public Item
{
    public:
        RuestungsItem( int verfuegbarkeit, int ruestung, int schnelligkeit, std::string name );
        ~RuestungsItem();
        int getRuestung() const { return itsRuestung; }
        int getSchnelligkeit() const { return itsSchnelligkeit; }
    protected:
        int itsRuestung;
        int itsSchnelligkeit;
};
class Kopfschutz : public RuestungsItem
{
    public:
        Kopfschutz( int verfuegbarkeit );
        ~Kopfschutz();
        int getRuestung() const { return itsRuestung; }
        int getSchnelligkeit() const { return itsSchnelligkeit; }
};
class TrankItem : public Item
{
    public:
        TrankItem( int verfuegbarkeit, int gesundheit, std::string name );
        ~TrankItem();
        int getGesundheit() const { return itsGesundheit; }
    protected:
        int itsGesundheit;
};
class HeilTrank20 : public TrankItem
{
    public:
        HeilTrank20( int verfuegbarkeit );
        ~HeilTrank20();
        int getGesundheit() const { return itsGesundheit; }
};
class ZauberItem : public Item
{
    public:
        ZauberItem( int verfuegbarkeit, int zauberfaehigkeit, std::string name );
        ~ZauberItem();
        int getZauberfaehigkeit() const { return itsZauberfaehigkeit; }
    protected:
        int itsZauberfaehigkeit;
};
class Zauberverstaerker3 : public ZauberItem
{
    public:
        Zauberverstaerker3( int verfuegbarkeit );
        ~Zauberverstaerker3();
        int getZauberfaehigkeit() const { return itsZauberfaehigkeit; }
};
#endif // CLASSITEMS_H_INCLUDED
classItems.cpp
Code:
#include "classItems.h"
#include <string>
using namespace std;
Item::Item( ItemTyp typ, int verfuegbarkeit, string name ):
    itsTyp( typ ), itsVerfuegbarkeit( verfuegbarkeit ), itsName( name )
{
}
Item::~Item()
{
}
WaffenItem::WaffenItem( int verfuegbarkeit, int schaden, int schnelligkeit, string name ):
    Item( WAFFE, verfuegbarkeit, name ), itsSchaden( schaden ), itsSchnelligkeit( schnelligkeit )
{
}
WaffenItem::~WaffenItem()
{
}
Schwert::Schwert( int verfuegbarkeit ):
    WaffenItem( verfuegbarkeit, 5, 2, "Schwert" )
{
}
Schwert::~Schwert()
{
}
Messer::Messer( int verfuegbarkeit ):
    WaffenItem( verfuegbarkeit, 3, 3, "Messer" )
{
}
Messer::~Messer()
{
}
RuestungsItem::RuestungsItem( int verfuegbarkeit, int ruestung, int schnelligkeit, string name ):
    Item( RUESTUNG, verfuegbarkeit, name ), itsRuestung( ruestung ), itsSchnelligkeit( schnelligkeit )
{
}
RuestungsItem::~RuestungsItem()
{
}
Kopfschutz::Kopfschutz( int verfuegbarkeit ):
    RuestungsItem( verfuegbarkeit, 3, 2, "Kopfschutz" )
{
}
Kopfschutz::~Kopfschutz()
{
}
TrankItem::TrankItem( int verfuegbarkeit, int gesundheit, string name ):
    Item( TRANK, verfuegbarkeit, name ), itsGesundheit( gesundheit )
{
}
TrankItem::~TrankItem()
{
}
HeilTrank20::HeilTrank20( int verfuegbarkeit ):
    TrankItem( verfuegbarkeit, 20, "Heil-Trank-20" )
{
}
HeilTrank20::~HeilTrank20()
{
}
ZauberItem::ZauberItem( int verfuegbarkeit, int zauberfaehigkeit, string name ):
    Item( ZAUBERWAFFE, verfuegbarkeit, name ), itsZauberfaehigkeit( zauberfaehigkeit )
{
}
ZauberItem::~ZauberItem()
{
}
Zauberverstaerker3::Zauberverstaerker3( int verfuegbarkeit ):
    ZauberItem( verfuegbarkeit, 3, "Zauberverstaerker3" )
{
}
Zauberverstaerker3::~Zauberverstaerker3()
{
}

Da ja in der Itemklasse noch keine Variablen wie itsSchaden vorhanden sind, kann ich den Rumpf ja auch nicht implementieren.
Daher habe ich sie ja abstract gemacht, so dann bekomm ich imer noch den fehler mit dem zuweisen, dass es nicht geht da die Funktionen abstract sind, obwohl ich sie für jede Klasse nun implementiert habe,
mach ich das abstrakt weg, funktioniert es leider auch nicht, dann bekomm ich wieder den fehler beim linken undefined reference to....

Weiß echt net mehr weiter...=(

Aber ich glaub noch dran dass wir das hinbekommen;-)

EDIT:
Die Fehlermeldung ist auch sehr komisch, er sagt mir er kann kein Kopfschutz allokieren, da getGesundheit, getZauberfaehigkeit abstract sind und er kann kein schwert machen, da getRuestung, getZauberfaehigkeit und getGesundheit abstract ist. Aber das komische ist, ein Kopfschutz hat nur getRuestung und getSchnelligkeit und braucht auch nur diese, genau wie ein Schwert nur getSchaden und getSchnelligkeit braucht.

Ich erkenne also glaub ich den Fehler, jedoch net die Ursache:D:(
 
Zuletzt bearbeitet:
Es ist egal, was du von der Logik her für die erbenden Klassen brauchst, wenn du sie instanziieren möchtest, muss eine Implementierung für alle Funktionen vorhanden sein. Entweder sieht also Item so aus:
Code:
class Item
{
      virtual int getSchaden()
      {return 0;}

      virtual int getZauberfaehigkeit()
      {return 0;}

      ...
};

class Schwert
{
      virtual int getSchaden()
      {
             //sinnvolle Implementierung
      }
};
Damit hätten dann alle Items einmal auf jeden Fall eine Implementierung. Oder du machst sie alle pure virtual, und musst sie dann jedes Mal implementieren. Manchmal halt eben ohne Sinn.
Code:
class Item
{
      virtual int getSchaden() = 0;
      virtual int getZauberfaehigkeit() = 0;
      ...
};

class Schwert
{
      virtual int getSchaden()
      {
             //sinnvolle Implementierung
      }

      virtual int getZauberfaehigkeit
      {
             //unsinnig, muss aber trotzdem da sein
             return 0;
      }
};
mfg benediktibk
 
Zurück
Oben