Du kan göra ett interface med Item som abstrakt basklass. (mha "virtual" )
Slotarrayen kan då ha datatypen Item och du binder in en ny pryttel i "ryggsäcken" med hjälp av
Item *p;
p->new Ring(); //eller vad det nu är
...
slot[xxx] = p;
Typ...
32 svar · 629 visningar · startad av Alpha II
Hej.
så här ser classerna ut i mitt textbaserade rpg spel:
class Creature
{
public:
string name;
int level;
// Stats
int strength;
int dextery;
int vitality;
int knowledge;
// Variables
int life;
};
class PlayerChar : public Creature
{
public:
int charClass;
int experience;
// Items
int weapon;
int chestPlate;
int ring;
int shield;
int helm;
int slot[9]; // array som ska innehålla sakerna man har med sig
// Other
int gold;
};
class EnemyChar : public Creature
{
public:
bool autoAttack;
int loot;
int weaponDamage;
int defense;
};
class Item
{
public:
string name;
};
class Weapon : public Item
{
public:
int damage;
};
class Chestplate : public Item
{
public:
int defense;
};
class Shield : public Item
{
public:
int defense;
};
class Helm : public Item
{
public:
int defense;
};
class Ring : public Item
{
public:
int life;
int strength;
int sextery;
int vitality;
int knowledge;
};
class Potion : public Item
{
public:
int type; // 0 - Healing
int points;
};
Jag har arrays med vapen, chestplate, shields, rings etc.
Hur ska jag göra så att man ska kunna ha vilken sorts saker som helst med sig i "ryggsäcken" (slot arrayen) eller vad det nu ska vara?
Du kan göra ett interface med Item som abstrakt basklass. (mha "virtual" )
Slotarrayen kan då ha datatypen Item och du binder in en ny pryttel i "ryggsäcken" med hjälp av
Item *p;
p->new Ring(); //eller vad det nu är
...
slot[xxx] = p;
Typ...
Fast det är ju enbart functioner som kan vara abstrakta.
Cirkel, kvadrat etc implementerar den abstrakta funktionen Draw som är pure virtual.
Vad du borde göra är en templateklass som wappar in dina typer av "Items". Sedan kan du lagra instanser av denna templateklass i din array.
Pseudokod :
Template <class T> GeneralItem
{
...
}
...
GeneralItems TheItems[MAX_SIZE]
Fast det är ju enbart functioner som kan vara abstrakta.
Nope. Du implementerar ju en abstrakt basklass som garanterar de metoder som skall finnas.
Men har du tänkt att bygga vidare på dina "Items" med en drös egenskaper eller ska de bara bestå av varsin datatyp? Om det senare är det ju vettigare med Beatbox variant.
Enklast skulle ju bara vara att enbart ha en klass och en ENUM som säger vad det är för typ av Item. Man får ju annas problematiken att försöka ta reda på vad det är annars. Om man lagarar nått generellt i en array och bara har tänkt anropa metoder så måste man ju ändå veta vad det är för att kunna göra rätt saker.
Om man lagarar nått generellt i en array och bara har tänkt anropa metoder så måste man ju ändå veta vad det är för att kunna göra rätt saker
Jamen det är ju det som är så fint med interface - att man inte behöver bry sig längre än vad som är definierat i interfacet
PeW skrev:
Du kan göra ett interface med Item som abstrakt basklass. (mha "virtual" )
Slotarrayen kan då ha datatypen Item och du binder in en ny pryttel i "ryggsäcken" med hjälp avItem *p; p->new Ring(); //eller vad det nu är ... slot[xxx] = p;Typ...
Det lät ju bra, men hur gör man det?
Så här... fördelen är att om du tänkt att bygga vidare med mer egenskaper så definierar du bara upp basklassen på nytt och justerar i underklasserna. Jag är på semester så följande är skrivet rakt upp och ned i all hast...
class Item {
public:
Item(){}
virtual ~Item(){}
virtual int getItem()=0;
};
// T.ex:
class Chestplate : public Item {
public:
Chestplate():defense(0){}
Chestplate(int d):defense(d){}
virtual int getItem() {return defense; }
private:
int defense;
};
class Shield: public Item {
public:
Shield():defense(0){}
Shield(int d):defense(d){}
virtual int getItem() {return defense;}
private:
int defense;
};
Nu kan man lätt peta in Items i t.ex en vector, länkad lista eller vad som helst
Item *p;
p=new Shield(999);
std::vector<Item> v;
v.push_back(p);
Sen loopa igenom när du ska använda prylarna
//for, whileloop eller en Iterator:
int p;
loop while something
p=v.at(index)->getItem();
_do something with p_
Med reservation för fullkomligt galen lösning
Det där läcker minne då man destruerar vectorn !
Jo men det är inget helt program eller hur?...
När man destruerar containern får man såklart loopa igenom och plocka bort varje med delete... men det kommer ju SEN beroende på hur man implementerar denna lösning
std::vector<Item> v;
Borde vara :
std::vector<Item*> v;
vector<..> lagrar en kopia och om man inte lagrar pekare så reserveras plats för en Item och kopieras dit. Eftersom man då inte kopierat resterande delar så smäller det, eller så har man tur om det inte smäller.
Hur ska getItem() se ut för ring?
Hur kan man få reda på om t ex slot[3] är en Potion?
Jag tycker du ska skita i att ärva från Item och lägga allt i en klass och sedan ha en ENUM som säger vad det är för nått. Det är skillnad om detskulle vara massvis med kod som ligger i Item, men nu är det inte det.
Hur ska getItem() se ut för ring?
Som i de andra klasserna... dvs leverera variabeln
Hur kan man få reda på om t ex slot[3] är en Potion?
Man kan ju peta in ytterligare en variabel som identifikation och lägga in ytterligare en metod som levererar denna.
//variabel:
std::string info
//i konstruktorerna:
Pryttel():info("Pryttel"), defense(xxx){}
// i Item:
virtual std::string getInfo()=0;
// i de andra:
virtual std::string getInfo(){ return info; }
...
men det är ju 5 variabler i ring...
C:\Program\Microsoft Visual Studio\MyProjects\QuestForIkara\main.cpp(335) : error C2228: left of '.getInfo' must have class/struct/union type
C:\Program\Microsoft Visual Studio\MyProjects\QuestForIkara\main.cpp(471) : error C2228: left of '.getInfo' must have class/struct/union type
C:\Program\Microsoft Visual Studio\MyProjects\QuestForIkara\main.cpp(473) : error C2228: left of '.getItem' must have class/struct/union type
----
if (enemy.loot)
{
AddItem(enemy.loot);
cout \<\< "The " \<\< (\*target).name \<\< " dropped " \<\< enemy.loot.getInfo() \<\< "!\\n";
}
Hur ska jag göra det här?
glöm min fråga löste det.
Får ju fel hela tiden.... det här var krånligt
class Item
{
public:
Item() {}
virtual ~Item() {}
virtual getItem()=0;
virtual string getInfo()=0;
virtual string getName()=0;
string info;
string name;
};
class Weapon : public Item
{
public:
Weapon():info("weapon"), damage(0) {}
Weapon(string n,int d):info("weapon"), name(n), damage(d) {}
virtual int getItem() { return damage; }
virtual string getInfo() { return info; }
virtual string getName() { return name; }
private:
int damage;
};
Fel:
Compiling...
main.cpp
c:\program\microsoft visual studio\myprojects\questforikara\main.hpp(20) : error C2614: 'Weapon' : illegal member initialization: 'info' is not a base or member
c:\program\microsoft visual studio\myprojects\questforikara\main.hpp(21) : error C2614: 'Weapon' : illegal member initialization: 'name' is not a base or member
c:\program\microsoft visual studio\myprojects\questforikara\main.hpp(21) : error C2614: 'Weapon' : illegal member initialization: 'info' is not a base or member
C:\Program\Microsoft Visual Studio\MyProjects\QuestForIkara\main.cpp(23) : error C2259: 'Potion' : cannot instantiate abstract class due to following members:
c:\program\microsoft visual studio\myprojects\questforikara\main.hpp(81) : see declaration of 'Potion'
C:\Program\Microsoft Visual Studio\MyProjects\QuestForIkara\main.cpp(23) : warning C4259: 'class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall Item::getName(void)' : pure virtual function was not define
d
c:\program\microsoft visual studio\myprojects\questforikara\main.hpp(11) : see declaration of 'getName'
C:\Program\Microsoft Visual Studio\MyProjects\QuestForIkara\main.cpp(67) : error C2664: '__thiscall Weapon::Weapon(const class Weapon &)' : cannot convert parameter 1 from 'const int' to 'const class Weapon &'
Reason: cannot convert from 'const int' to 'const class Weapon'
No constructor could take the source type, or constructor overload resolution was ambiguous
Error executing cl.exe.
main.obj - 5 error(s), 1 warning(s)
Du bör väl då även ta med variablerna info och name...
class Weapon : public Item
{
public:
Weapon():info("weapon"), damage(0) {}
Weapon(string n,int d):info("weapon"), name(n), damage(d) {}
virtual int getItem() { return damage; }
virtual string getInfo() { return info; }
virtual string getName() { return name; }
private:
int damage;
string info;
string name;
};