大家好,这是我在堆栈上的第一篇文章。我正在从马克李的一本书“绝对初学者的C++编程”中学习C++。目前,我正在通过制作一个关于龙的游戏来学习继承。我知道,创建定义的头文件和用于实现的cpp文件是很好的做法。但是,我遵循了这个人在书中所写的内容,并且在同一个文件.cpp中定义和编写了实现(我认为c++中仍然允许这样做,对吗?)无论如何,在完成它并试图编译之后,我得到了
龙的多重定义::攻击(Int)
这个错误出现在几乎所有的方法上。没有弹出的链接器错误。如果我解释得太久了,很抱歉。这是文件。预先谢谢你,如果有可能的话,我能保持类在同一个文件中的定义和实现的方式吗?
Dragon.cpp
#pragma once
#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 armor;
int treasure;
int clawDamage;
int size;
protected:
Dragon(int theSize);
int getArmor(){return armor;}
int& getHitPoints(){return hitPoints;}
int getClawDamage(){return clawDamage;}
int getSize() {return size;}
virtual int attack(int targetArmor, int specialDamage);
public:
virtual int attack(int targetArmor)=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=2*size;
hitPoints=4*size;
armor=size;
treasure=1000*size;
srand(time(0));
}
int Dragon::attack(int targetArmor, int specialDamage)
{
int useSpecial=rand()%2; //0 or 1
int damage;
if(useSpecial)
damage=specialDamage;
else
damage=getClawDamage();
return MAX(damage-targetArmor,0);
} BlackDragon.cpp
#include<string>
#include"Dragon.cpp"
using std::string;
class BlackDragon : public Dragon
{
private:
int poisonDamage;
public:
BlackDragon(int theSize);
int attack(int targetArmor);
void defend(int damage);
string getName(){return "Black Dragon";}
};
BlackDragon::BlackDragon(int theSize):Dragon(theSize)
{
poisonDamage=getSize();
}
int BlackDragon::attack(int targetArmor)
{
return Dragon::attack(targetArmor, poisonDamage);
}
void BlackDragon::defend(int damage)
{
getHitPoints()-=damage - getArmor();
}RedDragon.cpp
#include<string>
#include"Dragon.cpp"
using std::string;
class RedDragon : public Dragon
{
private:
int fireDamage;
public:
RedDragon(int theSize);
int attack(int targetArmor);
void defend(int damage);
string getName(){return "Red Dragon";}
};
RedDragon::RedDragon(int theSize):Dragon(theSize)
{
fireDamage=4*getSize();
}
int RedDragon::attack(int targetArmor)
{
return Dragon::attack(targetArmor, fireDamage);
}
void RedDragon::defend(int damage)
{
getHitPoints()-=(damage-getArmor())/3;
}BlueDragon.cpp
#include<string>
#include"Dragon.cpp"
using std::string;
class BlueDragon: public Dragon
{
private:
int iceDamage;
public:
BlueDragon(int theSize);
int attack(int targetArmor);
void defend(int damage);
string getName(){return "Blue Dragon";}
};
BlueDragon::BlueDragon(int theSize):Dragon(theSize)
{
iceDamage=3*getSize();
}
int BlueDragon::attack(int targetArmor)
{
return Dragon::attack(targetArmor, iceDamage);
}
void BlueDragon::defend(int damage)
{
getHitPoints()-=(damage-getArmor())/2;
}DragonLord.cpp
#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));
Dragon* dragons[3];
int hp=15;
int armor=2;
int tempArmor;
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 princess."
<<"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;
tempArmor=armor;
}
else
{
tempAttack=rand()%11;
tempArmor=armor+4;
}
hp-=d->attack(armor);
d->defend(rand()%16-5);
cout<<"\nYou deliver a mighty blow and deel "<<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 ahve slain the dragon!"
<<"Congratulations.\n"
<<"the Princess is saved. \n";
return 0;
RUN:
cout<<"\nYou ahve fled in cowardice.\n";
return 0;
}
int menuChoice()
{
using std::cout;
using std::cin;
int choice;
do{
cout<<"\n[1]Atack\n"
<<"[2]Defensive Mode\n"
<<"[3]Run Away\n";
cin>>choice;
}while(choice<1&& choice>3);
return choice;
}发布于 2014-06-01 16:18:10
您正在.cpp文件中定义类,并多次包含它们。例如,当您在BlackDragon.cpp和BlackDragon.cpp中包括BlackDragon.cpp时,Dragon类中的所有内容都有两个定义。这将导致这个问题(破坏一种定义规则)。
有一些方法可以避免这种情况,但在C++中,最常见和最简单的做法是在头(.h)文件中声明类,并在.cpp文件中实现这些方法。如果需要在另一个类中定义一个类,则包括.h文件。
你可以这样做:
//Dragon.h
class Dragon
{
private:
int speed;
string name;
int hitPoints;
int armor;
/// other variables and methods
}
//Dragon.cpp
#include"Dragon.h"
//implement methods然后在继承类中
//BlueDragon.h
#include"Dragon.h"
//BlueDragon Class definition
//BlueDragon.cpp
#include "BlueDragon.h"
//BlueDragon methods implementation发布于 2014-06-01 16:45:05
您正在包括".cpp“文件。这是个很糟糕的主意。实际上,您应该在头文件中定义类,并在cpp文件中实现它们。这样,您就不会公开您的实现,只公开您的接口,并且每个符号只编译一次。这应该能解决你的问题。
此外,在某些情况下,您可能希望在头文件中实现方法,比如在创建模板类时,但是您不应该包含任何不是头文件的方法。
您的书似乎有点过时,使用宏而不是std::max和诸如此类。你也许应该拿一本关于C++11的新的,闪亮的书。
https://stackoverflow.com/questions/23981842
复制相似问题