Greetings,
I've looked for a site the published might like people to go to with questions. Unfortunately I can't find one so I'd like to ask here. I'm reviewing C++ with a new book. In the book one of the lessons is on Classes. There are 5 separate Cpp files.
BlackDragon
BlueDragon
RedDragon
Dragon
DragonLord
The book does not have you include the Dragon.cpp with the blue, red or blackdragon cpp files. So they don't know what the base class is. When you add it it you get all kinds of errors.
Here is the RedDragon. Blue and Black have the exact same code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
#include <string>
#include "Dragon.cpp"
using std::string;
class RedDragon : public Dragon
{
private:
int fireDamage;
public:
RedDragon(int theSize);
int attack(int targetArmour);
void defend(int damage);
string getName() {return "Red Dragon";}
};
RedDragon::RedDragon(int theSize) : Dragon(theSize)
{
fireDamage = 4 * getSize();
}
int RedDragon::attack(int targetArmour)
{
return Dragon::attack(targetArmour, fireDamage);
}
void RedDragon::defend(int damage)
{
getHitPoints() -= (damage - getArmour())/3;
}
|
Now the base class (Dragon.cpp)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
|
#include <string>
#include <ctime>
#include <cstdlib>
using std::string;
#define MAX(a,b) a>b? a:b
class Dragon
{
private:
int speed;
string name;
int hitPoints;
int armour;
int treasure;
int clawDamage;
int size;
protected:
Dragon(int theSize);
int getArmour() {return armour;}
int& getHitPoints() {return hitPoints;}
int getClawDamage() {return clawDamage;}
int getSize() {return size;}
virtual int attack(int targetArmour, int specialDamage);
public:
virtual int attack(int targetArmour) = 0;
virtual void defend(int damage) = 0;
int getTreasure() {return treasure;}
virtual string getName() {return name;}
int getSpeed() {return speed;}
bool isAlive() {return hitPoints > 0;}
};
Dragon::Dragon(int theSize) : size(theSize)
{
if (size < 1 || size > 4)
size = 3;
clawDamage = 2 * size;
speed = 3 * size;
hitPoints = 4 * size;
armour = 1000 * size;
srand(time(0));
}
int Dragon::attack(int targetArmour, int specialDamage)
{
int useSpecial = rand() % 2; // 0 or 1
int damage;
if (useSpecial)
damage = specialDamage;
else
damage = getClawDamage();
return MAX(damage - targetArmour,0);
}
|
And finally DragonLord.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
|
#include <iostream>
#include <ctime>
#include <cstdlib>
#include "Dragon.cpp"
#include "RedDragon.cpp"
#include "BlueDragon.cpp"
#include "BlackDragon.cpp"
int menuChoice();
int main(void)
{
using std::srand;
using std::time;
using std::rand;
using std::cout;
srand((unsigned int)time(0)); //Seeding random
Dragon* dragons[3];
int hp = 15;
int armour = 2;
int tempArmour;
int tempAttack;
dragons[0] = new RedDragon(rand() % 4+1);
dragons[1] = new BlackDragon(rand() % 4+1);
dragons[2] = new BlueDragon(rand() % 4+1);
Dragon* d = dragons[rand()%3];
cout<<"Welcome noble knight.\n"
<<"You must save a pricess." <<" She has been captured by a "
<<d->getName() <<".\n" <<"You must defeat the dragon.\n";
cout<<"Your hit points are: " <<hp <<"\n";
while(d->isAlive() && hp>0)
{
int choice = menuChoice();
if (choice == 3)
goto RUN;
else if (choice == 1)
{
tempAttack = rand()%16+5;
tempArmour = armour + 4;
}
else
{
tempAttack = rand()%11;
tempArmour = armour + 4;
}
hp -= d->attack(armour);
d->defend(rand()%16-5);
cout<<"\nYou deliver a might blow and deal " << tempAttack <<" damage.\n";
cout<<"Your hit points are: " << hp;
}
if (d->isAlive())
cout<<"\nYou have perished before the might of the dragon.\n";
else
cout<<"\n\nYou have slain the dragon! Congratulations.\n The Princess is saved.\n";
return 0;
RUN:
cout<<"\nYou have fled in cowardice.\n";
return 0;
}
int menuChoice()
{
using std::cout;
using std::cin;
int choice;
do {
cout<<"\n[1]Attack\n" <<"[2]Defensive Mode\n" <<"[3]Run Away\n";
cin>>choice;
} while (choice < 1 && choice > 3);
return choice;
}
|
So leaving "Dragon.cpp" in the mix I get the following error.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
LNK2005: "protected: __thiscall Dragon::Dragon(int)" (??0Dragon@@IAE@H@Z) already defined in BlackDragon.obj
1>BlueDragon.obj : error LNK2005: "protected: virtual int __thiscall Dragon::attack(int,int)" (?attack@Dragon@@MAEHHH@Z) already defined in BlackDragon.obj
1>Dragon.obj : error LNK2005: "protected: __thiscall Dragon::Dragon(int)" (??0Dragon@@IAE@H@Z) already defined in BlackDragon.obj
1>Dragon.obj : error LNK2005: "protected: virtual int __thiscall Dragon::attack(int,int)" (?attack@Dragon@@MAEHHH@Z) already defined in BlackDragon.obj
1>DragonLord.obj : error LNK2005: "protected: __thiscall Dragon::Dragon(int)" (??0Dragon@@IAE@H@Z) already defined in BlackDragon.obj
1>DragonLord.obj : error LNK2005: "protected: virtual int __thiscall Dragon::attack(int,int)" (?attack@Dragon@@MAEHHH@Z) already defined in BlackDragon.obj
1>DragonLord.obj : error LNK2005: "public: __thiscall BlueDragon::BlueDragon(int)" (??0BlueDragon@@QAE@H@Z) already defined in BlueDragon.obj
1>DragonLord.obj : error LNK2005: "public: virtual int __thiscall BlueDragon::attack(int)" (?attack@BlueDragon@@UAEHH@Z) already defined in BlueDragon.obj
1>DragonLord.obj : error LNK2005: "public: virtual void __thiscall BlueDragon::defend(int)" (?defend@BlueDragon@@UAEXH@Z) already defined in BlueDragon.obj
1>DragonLord.obj : error LNK2005: "public: __thiscall BlackDragon::BlackDragon(int)" (??0BlackDragon@@QAE@H@Z) already defined in BlackDragon.obj
1>DragonLord.obj : error LNK2005: "public: virtual int __thiscall BlackDragon::attack(int)" (?attack@BlackDragon@@UAEHH@Z) already defined in BlackDragon.obj
1>DragonLord.obj : error LNK2005: "public: virtual void __thiscall BlackDragon::defend(int)" (?defend@BlackDragon@@UAEXH@Z) already defined in BlackDragon.obj
1>RedDragon.obj : error LNK2005: "protected: __thiscall Dragon::Dragon(int)" (??0Dragon@@IAE@H@Z) already defined in BlackDragon.obj
1>RedDragon.obj : error LNK2005: "protected: virtual int __thiscall Dragon::attack(int,int)" (?attack@Dragon@@MAEHHH@Z) already defined in BlackDragon.obj
1>RedDragon.obj : error LNK2005: "public: __thiscall RedDragon::RedDragon(int)" (??0RedDragon@@QAE@H@Z) already defined in DragonLord.obj
1>RedDragon.obj : error LNK2005: "public: virtual int __thiscall RedDragon::attack(int)" (?attack@RedDragon@@UAEHH@Z) already defined in DragonLord.obj
1>RedDragon.obj : error LNK2005: "public: virtual void __thiscall RedDragon::defend(int)" (?defend@RedDragon@@UAEXH@Z) already defined in DragonLord.obj
1>c:\users\seanr\documents\visual studio 2010\Projects\DragonLore\Debug\DragonLore.exe : fatal error LNK1169: one or more multiply defined symbols found
1>
1>Build FAILED.
1>
1>Time Elapsed 00:00:00.76
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
|
So then I remove the "Dragon.cpp" from the blue, black and red.
error C2653: 'Dragon' : is not a class or namespace name
I've also tried converting the Dragon.cpp into a header file and then putting guards into place. I can't seem to get this to compile. I am real rust and using the lessons to better understand how everything works.
I've also done some googling. I wasn't able to find anything definitive. Any advise would be grateful.