首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >方法错误的C++多重定义;学习继承

方法错误的C++多重定义;学习继承
EN

Stack Overflow用户
提问于 2014-06-01 16:14:32
回答 2查看 1.1K关注 0票数 0

大家好,这是我在堆栈上的第一篇文章。我正在从马克李的一本书“绝对初学者的C++编程”中学习C++。目前,我正在通过制作一个关于龙的游戏来学习继承。我知道,创建定义的头文件和用于实现的cpp文件是很好的做法。但是,我遵循了这个人在书中所写的内容,并且在同一个文件.cpp中定义和编写了实现(我认为c++中仍然允许这样做,对吗?)无论如何,在完成它并试图编译之后,我得到了

龙的多重定义::攻击(Int)

这个错误出现在几乎所有的方法上。没有弹出的链接器错误。如果我解释得太久了,很抱歉。这是文件。预先谢谢你,如果有可能的话,我能保持类在同一个文件中的定义和实现的方式吗?

Dragon.cpp

代码语言:javascript
复制
#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

代码语言:javascript
复制
#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

代码语言:javascript
复制
#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

代码语言:javascript
复制
#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

代码语言:javascript
复制
#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;
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-06-01 16:18:10

您正在.cpp文件中定义类,并多次包含它们。例如,当您在BlackDragon.cpp和BlackDragon.cpp中包括BlackDragon.cpp时,Dragon类中的所有内容都有两个定义。这将导致这个问题(破坏一种定义规则)。

有一些方法可以避免这种情况,但在C++中,最常见和最简单的做法是在头(.h)文件中声明类,并在.cpp文件中实现这些方法。如果需要在另一个类中定义一个类,则包括.h文件。

你可以这样做:

代码语言:javascript
复制
//Dragon.h
class Dragon
{
  private:
          int speed;
          string name;
          int hitPoints;
          int armor;
  /// other variables and methods
}

//Dragon.cpp
 #include"Dragon.h"


//implement methods

然后在继承类中

代码语言:javascript
复制
//BlueDragon.h
 #include"Dragon.h"

 //BlueDragon Class definition

//BlueDragon.cpp
#include "BlueDragon.h"
//BlueDragon methods implementation
票数 1
EN

Stack Overflow用户

发布于 2014-06-01 16:45:05

您正在包括".cpp“文件。这是个很糟糕的主意。实际上,您应该在头文件中定义类,并在cpp文件中实现它们。这样,您就不会公开您的实现,只公开您的接口,并且每个符号只编译一次。这应该能解决你的问题。

此外,在某些情况下,您可能希望在头文件中实现方法,比如在创建模板类时,但是您不应该包含任何不是头文件的方法。

您的书似乎有点过时,使用宏而不是std::max和诸如此类。你也许应该拿一本关于C++11的新的,闪亮的书。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23981842

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档