|
JLI Spieleprogrammierung
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Jonathan_Klein Living Legend
Alter: 37 Anmeldedatum: 17.02.2003 Beiträge: 3433 Wohnort: Siegerland Medaillen: Keine
|
Verfasst am: 06.04.2006, 14:48 Titel: Zuweisungsoperator: |
|
|
Hi, ich hab so das Gefpühl das hier ganz gewaltig was net stimmt:
CPP: | class Character
[...]
protected:
long CalcExperience(long Level, long NeededExperience);
GamePointers m_Game;
ManagedAnimatedSprite m_WalkAni[8], m_StandAni[8], m_AttackAni[8], m_CorpseAni;
int SpriteIndex;//welche animation laufen soll
std::string m_AttackSound;
Inventar m_Inventar;
int m_Status;//0=stehen, 1=laufen, 2=GetItem (für player), 4=angreifen, 5=leiche
int m_SpriteSizeX, m_SpriteSizeY;//für den test ob die maus über dem objekt ist
//physikalische größen
float m_XPos, m_YPos;
float m_DestinationX, m_DestinationY;
float DirectionX, DirectionY; //normalisierter bewegungsvektor, winkel
//Basischarakterwerte:
std::string m_Name;
float m_Hitpoints;
float m_MaxHitpoints;
Damage m_MinDamage;
Damage m_MaxDamage;
Damage m_MinArmor;
Damage m_MaxArmor;
float m_AttackVar;//für angriffs und abwehrwahrscheinlichkeit
float m_DefenseVar;
float m_AttackSpeed;
float m_DamageAt;
Character *m_Target;
float m_AttackCounter;//zählt die Zeit bis zur nächsten attacke runter
float m_WalkSpeed;
float m_Radius;
float m_AttackRange;
int m_Team;//1=Player
float m_ViewDistance;//radius in dem NPC's ihre gegner angreifen
const int m_ID;
long m_CollectedExperience;//die erfahrung die der character bisher gesmmelt hat
long m_SpreadExperience;//die ERfahrung die ein Character bekommt wenn er diesen tötet
long m_NeededExperience;//die erfahrung, die man für das nächste level braucht
long m_Level;//welches Characterlevel der Held shcon erreicht hat
static int IDCounter;
|
CPP: | class Player : public Character
[...]
protected:
Weapon m_ActiveWeapon;
int m_SkillLevel[2];//array das speichert welcher skill auf welchem level ist
float m_BaseMaxHitpoints;
float m_BaseAttackSpeed;
float m_BaseWalkSpeed;
float m_BaseAttackRange;
bool m_StayThere;
[...]
Player& Player::operator = (const Player& rhsObj)
{
cLog::GetInstance() << LOGI("Playerobjekt kopieren");
memcpy(this, &rhsObj, sizeof(Player));
m_Inventar=rhsObj.m_Inventar;
memcpy(m_WalkAni, rhsObj.m_WalkAni, sizeof(ManagedAnimatedSprite)*8);
memcpy(m_StandAni, rhsObj.m_StandAni, sizeof(ManagedAnimatedSprite)*8);
memcpy(m_AttackAni, rhsObj.m_AttackAni, sizeof(ManagedAnimatedSprite)*8);
memcpy(m_SkillLevel, rhsObj.m_SkillLevel, sizeof(int)*2);
return *this;
}
|
CPP: | class Inventar[...]
protected:
GamePointers m_Game;
std::list<Weapon> m_WeaponList;
std::map<std::string, MultiItem> m_MultiItemMap;
[...]
Inventar& Inventar::operator = (const Inventar& rhsObj)
{
cLog::GetInstance() << LOGI("Inventar kopieren");
m_Game=rhsObj.m_Game;
m_WeaponList=rhsObj.m_WeaponList;
m_MultiItemMap=rhsObj.m_MultiItemMap;
return *this;
}
|
Jedenfalls stürtzt er ab wenn ich auf das Inventar zugreifen möchte, nachdem ich mein Playerobjekt einmal kopiert habe. _________________ https://jonathank.de/games/ |
|
Nach oben |
|
|
DirectXer Dark JLI'ler
Anmeldedatum: 05.02.2005 Beiträge: 1201 Wohnort: Köln Medaillen: Keine
|
Verfasst am: 06.04.2006, 17:31 Titel: |
|
|
nur mal so ganz spontan, kann sein dass es falsch ist: CPP: | Inventar& Inventar::operator = (const Inventar& rhsObj)
{
cLog::GetInstance() << LOGI("Inventar kopieren");
m_Game=rhsObj.m_Game;
m_WeaponList=rhsObj.m_WeaponList;
m_MultiItemMap=rhsObj.m_MultiItemMap;
return *this;
} |
du greifst hier auf Objekte von rhsObj zu, die protected sind. Das is eigentlich verboten... Daher kanns sein, dass die Datein net ordnungsgemäß kopiert sind und du deshalb net drauf zugreifen kannst
Gruß DXer
EDIT: Beim Zuweisungsop. von Player kopierst du einige Member von Character, wird da net der compilergenerierte Kopierzuweisungsoperator von Character automatisch aufgerufen? So dass das alles kopiert wird? weil ich in character keinen eigenen von dir sehe |
|
Nach oben |
|
|
Jonathan_Klein Living Legend
Alter: 37 Anmeldedatum: 17.02.2003 Beiträge: 3433 Wohnort: Siegerland Medaillen: Keine
|
Verfasst am: 06.04.2006, 18:44 Titel: |
|
|
Ich habe einen eigenen Zuweisugnoperator von Character, dieser wird jedoch definitiv nicht aufgerufen (er macht auch n Logbucheintrag, bzw. eben nicht).
Das ich auf die Protected Elemente zugreife ist kalr, nur das muss ich doch irgendwie, oder net? Ich muss dohc im Prinzip jedem Element das entsprechende von dem Übergebenen Objekt zuweisen. Da ich als Inventar auf protected-Objekte eines Inventars zugreife müsste das doch gehen, oder nicht? Bzw. wie sollte es sonst gehen? _________________ https://jonathank.de/games/ |
|
Nach oben |
|
|
DirectXer Dark JLI'ler
Anmeldedatum: 05.02.2005 Beiträge: 1201 Wohnort: Köln Medaillen: Keine
|
Verfasst am: 06.04.2006, 19:02 Titel: |
|
|
Jonathan_Klein hat Folgendes geschrieben: | Ich habe einen eigenen Zuweisugnoperator von Character, dieser wird jedoch definitiv nicht aufgerufen (er macht auch n Logbucheintrag, bzw. eben nicht).
Das ich auf die Protected Elemente zugreife ist kalr, nur das muss ich doch irgendwie, oder net? Ich muss dohc im Prinzip jedem Element das entsprechende von dem Übergebenen Objekt zuweisen. Da ich als Inventar auf protected-Objekte eines Inventars zugreife müsste das doch gehen, oder nicht? Bzw. wie sollte es sonst gehen? |
naja, kann sein dass es geht, ich bin mir eher unsicher damit... probiers doch mal mit friend Aber selbst wenns gehen sollte, du greifst in Player auf Protecteds von Character zu, das ginge dann wahrscheinlich net, upcasten, also bei Vererbung auf höhere klassen bei protected; da kommt schon einiges zusammen |
|
Nach oben |
|
|
Jonathan_Klein Living Legend
Alter: 37 Anmeldedatum: 17.02.2003 Beiträge: 3433 Wohnort: Siegerland Medaillen: Keine
|
Verfasst am: 06.04.2006, 19:28 Titel: |
|
|
hm, ich versteh das ganze net so (hab ncoh fast nie was mit vererbung gemafcht). Character hat als "Freund" den Player, allerdings ist protected doch gerade dafür da, das man damit als "Kind" auf die Elemente seiner Basisklasse zugreifen darf, oder?
Was ist den mit dem memcpy, also die Idee dahinter war, einfach erstmal ne flache Kopie zu erzeugen, und dann von Arrays und Pointern (von denen von denen mans wirklich machen muss) eine Tiefe Kopie zu erzeugen. Ist das so überhaupt ok? _________________ https://jonathank.de/games/ |
|
Nach oben |
|
|
Chriss Senior JLI'ler
Anmeldedatum: 18.08.2004 Beiträge: 267
Medaillen: Keine
|
Verfasst am: 06.04.2006, 20:22 Titel: |
|
|
Zitat: |
allerdings ist protected doch gerade dafür da, das man damit als "Kind" auf die Elemente seiner Basisklasse zugreifen darf, oder?
|
durch diese definition
CPP: | class Player : public Character
|
werden alle protected Elemente der Elternklasse zu public Elementen der Kindklasse |
|
Nach oben |
|
|
DirectXer Dark JLI'ler
Anmeldedatum: 05.02.2005 Beiträge: 1201 Wohnort: Köln Medaillen: Keine
|
Verfasst am: 07.04.2006, 12:47 Titel: |
|
|
also, ok: so wie criss es sagt, stimmts. Allerdings hat deine Kindklasse (hier: Player) nur Zugriff auf die eigenen Basisklassenobjekte. Du hast in der Kindklasse nicht Zugriff auf Basisklassenmember anderer abgeleiteten protected/private Objekte; geschweige denn die dortigen protected member. Stell dir das so vor (ich denke, du weißt das schon längst, aber egal ): Code: |
public: jeder hat Zugriff
private: keiner " " (außer die eigene Klasseninstanz)
prtected: " " " ( " " " " und die Instanzen der abgeleiteten Klasse) |
So. Zu deiner Frage, die ungefähr so war: "Wie kann dann der compilergenerierte Kopierzuweisungsoperator auf die protected/private elemente der anderen Klasse (bei dir: rhsObj) Zugriff haben?" Dieser Operator greift net wirklich auf deine Elemente zu und kopiert diese, sondern er liest alle Bits die im Speicher von deinem Klassenanfang bis zum Klassen ende stehen, und schreibt genau diese Bits passend in den Teil des Speichers der anderen Klasse. d.h. er greift net wirklich auf die Member zu, sondern nur auf deren Bits, weshalb da das private und protected usw. net gilt
Gruß DXer |
|
Nach oben |
|
|
David Super JLI'ler
Alter: 39 Anmeldedatum: 13.10.2005 Beiträge: 315
Medaillen: Keine
|
Verfasst am: 07.04.2006, 13:09 Titel: |
|
|
Hi!
Ich hab das gefühl da Fehlt eine wichtige Info... Zeigmal den Quellcode wo du dein Objekt kopierst. Und bei was genau stürzt dein Programm ab?
Übrigens würd ich mir diesen Quellcode nochmals sehr gründlich überdenken...
Zitat: |
public: jeder hat Zugriff
private: keiner " " (außer die eigene Klasseninstanz)
prtected: " " " ( " " " " und die Instanzen der abgeleiteten Klasse)
|
Auf Private Elemente haben außerdem noch befreundete Methoden und Klassen zugriff.
grüße |
|
Nach oben |
|
|
OLiver Super JLI'ler
Alter: 33 Anmeldedatum: 29.06.2003 Beiträge: 306 Wohnort: Jena Medaillen: Keine
|
Verfasst am: 07.04.2006, 13:58 Titel: |
|
|
Zitat: |
werden alle protected Elemente der Elternklasse zu public Elementen der Kindklasse
|
Die werden private, nicht public. _________________ http://www.sieder25.org/ (Siedler 2 - Remake) |
|
Nach oben |
|
|
David Super JLI'ler
Alter: 39 Anmeldedatum: 13.10.2005 Beiträge: 315
Medaillen: Keine
|
Verfasst am: 07.04.2006, 15:08 Titel: |
|
|
Hi!
Wenn eine Klasse von einer zweiten öffentliche Erbt, dann kann diese auf geschützte Member der Elternklasse zugreifen. Diese ändern aber ihre Zugriffsspezifikation nicht, sie werden nicht public und nicht privat sondern bleiben ganz einfach protected.
grüße |
|
Nach oben |
|
|
Jonathan_Klein Living Legend
Alter: 37 Anmeldedatum: 17.02.2003 Beiträge: 3433 Wohnort: Siegerland Medaillen: Keine
|
Verfasst am: 07.04.2006, 18:23 Titel: |
|
|
Also, es stürztt ab sobald ich auf die STL Objekte der Inventarklasse zugreifen möchte. Interessatnerweise kann ich zum Beispiel die Größe (also .size()) Abfragen aber sobald ich ein neues Element hinzufüge oder ein vorhandenes lesen möchte, crasht es.
Kann ich STL-Container den so per Zuweisung kopeiren? Also eine tiefe Kopie erzeugen? Wenn nicht wäre ja klar wo der Fehelr leigt, .size() könnte den Wert einer internen Varaible einer falchen Kopie des containers zurückgebne, aber sobald die Zeiger ins Spiel kommen haben diese ungültige Adressen. _________________ https://jonathank.de/games/ |
|
Nach oben |
|
|
DirectXer Dark JLI'ler
Anmeldedatum: 05.02.2005 Beiträge: 1201 Wohnort: Köln Medaillen: Keine
|
Verfasst am: 07.04.2006, 18:49 Titel: |
|
|
Jonathan_Klein hat Folgendes geschrieben: | Also, es stürztt ab sobald ich auf die STL Objekte der Inventarklasse zugreifen möchte. Interessatnerweise kann ich zum Beispiel die Größe (also .size()) Abfragen aber sobald ich ein neues Element hinzufüge oder ein vorhandenes lesen möchte, crasht es.
Kann ich STL-Container den so per Zuweisung kopeiren? Also eine tiefe Kopie erzeugen? Wenn nicht wäre ja klar wo der Fehelr leigt, .size() könnte den Wert einer internen Varaible einer falchen Kopie des containers zurückgebne, aber sobald die Zeiger ins Spiel kommen haben diese ungültige Adressen. |
jedes STL-Template hat den Zuweisungsop. = allerdings ist das Verhalten nicht bei jedem so, wie man sich das vorstellt, gibt halt auch kleine Macken bei der STL. z.B. std::auto_ptr setzt beim Op. = den aufrufenden Pointer auf die Adresse des rechten Operants und diesen rechten dann auf NULL; naja, aber im Allgemeinen hat das jeder.
Gruß DXer |
|
Nach oben |
|
|
Jonathan_Klein Living Legend
Alter: 37 Anmeldedatum: 17.02.2003 Beiträge: 3433 Wohnort: Siegerland Medaillen: Keine
|
Verfasst am: 07.04.2006, 19:45 Titel: |
|
|
Ok, ich habe versuch die STL-Container des Inventars per Hand zu kopieren:
CPP: | Inventar& Inventar::operator = (const Inventar& rhsObj)
{
cLog::GetInstance() << LOGI("Inventar kopieren");
m_Game=rhsObj.m_Game;
m_WeaponList.clear();
std::list<Weapon>::iterator WeaponIt;
for(WeaponIt=rhsObj.m_WeaponList.begin(); WeaponIt!=rhsObj.m_WeaponList.end(); ++WeaponIt)
{
m_WeaponList.push_back(*WeaponIt);
}
m_MultiItemMap.clear();
std::map<std::string, MultiItem>::iterator ItemIt;
for(ItemIt=rhsObj.m_MultiItemMap.begin(); ItemIt!=rhsObj.m_MultiItemMap.end(); ++ItemIt)
{
m_MultiItemMap[ItemIt->first]=ItemIt->second;
}
//m_WeaponList=rhsObj.m_WeaponList;
//m_MultiItemMap=rhsObj.m_MultiItemMap;
return *this;
}
|
Code: |
error C2679: Binärer Operator '=': Es konnte kein Operator gefunden werden, der einen rechtsseitigen Operator vom Typ 'std::list<_Ty>::const_iterator' akzeptiert (oder keine geeignete Konvertierung möglich)
|
(Jeweils im Kopf der for-Schleife)
WEnn ich das const von rhsObj entferne, lässt es sich zwar kompilierne aber nciht linken, ich bekomme ein unaufgelösten externen Verweis, weil der Compielr wohl einen Zuweisungsoperator mit cons möchte. Ich ja eigentilch auch. Weiso meckert der in der for-Schleife überhaupt darüber das der Iterator const ist? Wieso ist er das überhaupt? _________________ https://jonathank.de/games/ |
|
Nach oben |
|
|
Kampfhund Super JLI'ler
Alter: 42 Anmeldedatum: 20.07.2002 Beiträge: 408
Medaillen: Keine
|
Verfasst am: 07.04.2006, 20:05 Titel: |
|
|
hm, ka obs daran liegt:
rhsObj ist eine const-Referenz. Daher kannst du nur methoden die selber const sind an dem objekt aufrufen und dir kann deswegen nur ein const-iterator zurückgeliefert werden.
edit:
CPP: | iterator begin()
{ // return iterator for beginning of mutable sequence
return (iterator(_Nextnode(_Myhead), this));
}
const_iterator begin() const
{ // return iterator for beginning of nonmutable sequence
return (const_iterator(_Nextnode(_Myhead), this));
}
|
Es gibt also zwei Versionen von begin(). Die eine gibt einen einfachen iterator und die andere einen const-iterator zurück. Da rhsObj eine const reference ist, kann nur die const Version aufgerufen werden. Du erhälst also einen const-iterator zurück. _________________ Kochen ist ein NP-schweres Optimierungsproblem. |
|
Nach oben |
|
|
Dragon Super JLI'ler
Alter: 38 Anmeldedatum: 24.05.2004 Beiträge: 340 Wohnort: Sachsen Medaillen: Keine
|
Verfasst am: 08.04.2006, 06:57 Titel: |
|
|
Jonathan_Klein hat Folgendes geschrieben: | Ok, ich habe versuch die STL-Container des Inventars per Hand zu kopieren:
CPP: | Inventar& Inventar::operator = (const Inventar& rhsObj)
{
cLog::GetInstance() << LOGI("Inventar kopieren");
m_Game=rhsObj.m_Game;
m_WeaponList.clear();
std::list<Weapon>::iterator WeaponIt;
for(WeaponIt=rhsObj.m_WeaponList.begin(); WeaponIt!=rhsObj.m_WeaponList.end(); ++WeaponIt)
{
m_WeaponList.push_back(*WeaponIt);
}
m_MultiItemMap.clear();
std::map<std::string, MultiItem>::iterator ItemIt;
for(ItemIt=rhsObj.m_MultiItemMap.begin(); ItemIt!=rhsObj.m_MultiItemMap.end(); ++ItemIt)
{
m_MultiItemMap[ItemIt->first]=ItemIt->second;
}
//m_WeaponList=rhsObj.m_WeaponList;
//m_MultiItemMap=rhsObj.m_MultiItemMap;
return *this;
}
|
Code: |
error C2679: Binärer Operator '=': Es konnte kein Operator gefunden werden, der einen rechtsseitigen Operator vom Typ 'std::list<_Ty>::const_iterator' akzeptiert (oder keine geeignete Konvertierung möglich)
|
(Jeweils im Kopf der for-Schleife)
WEnn ich das const von rhsObj entferne, lässt es sich zwar kompilierne aber nciht linken, ich bekomme ein unaufgelösten externen Verweis, weil der Compielr wohl einen Zuweisungsoperator mit cons möchte. Ich ja eigentilch auch. Weiso meckert der in der for-Schleife überhaupt darüber das der Iterator const ist? Wieso ist er das überhaupt? |
probier mal const_iterator statt iterator _________________ Nur wenn man ein Ziel sieht, kann man es auch treffen.
___________
Mein Leben, Freunde und die Spieleentwicklung |
|
Nach oben |
|
|
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
Powered by phpBB © 2001, 2005 phpBB Group Deutsche Übersetzung von phpBB.de
|