对复制构造函数和构造函数的未定义引用

undefined reference to copy ctor and ctor

我在这个文件中有一个基地 class:

#ifndef MTM_CHARACTER_H_
#define MTM_CHARACTER_H_
#include "Exceptions.h"
#include "Auxiliaries.h"
#include <memory>

namespace mtm
{
    
  class Character
  {
      protected:
              int health
               
      public:
              
             Character(int health): health(health){}
             virtual Character* clone() const = 0;
        
};
}
#endif

然后我得到了class:

#ifndef MTM_SNIPER_H_
#define MTM_SNIPER_H_
#include "Character.h"
#include <memory>
namespace mtm
{
 
 class Sniper: public Character
 {
     private:
            units_t successful_attack;
   public:
    Sniper(int health,units_t successful_attack=0): 
    Character(health), successful_attack(successful_attack){}
    virtual Character* clone() const override
    {
          return  new Sniper(*this) ;
    }
 
};
}
#endif

无论我做什么,我都会不断收到这些错误:

/tmp/cc5TyEEH.o:(.gcc_except_table+0xbc): undefined reference to `typeinfo for mtm::Character'
/tmp/ccbNL933.o: In function `mtm::Character::Character(mtm::Character const&)':
/home/raghad-a/mtm3_3/Character.h:25: undefined reference to `vtable for mtm::Character'
/tmp/ccbNL933.o:(.rodata._ZTIN3mtm5MedicE[_ZTIN3mtm5MedicE]+0x10): undefined reference to `typeinfo for mtm::Character'
/tmp/ccrnaFqr.o:(.rodata._ZTIN3mtm6SniperE[_ZTIN3mtm6SniperE]+0x10): undefined reference to `typeinfo for mtm::Character'
/tmp/ccGBmaWP.o:(.rodata._ZTIN3mtm7SoldierE[_ZTIN3mtm7SoldierE]+0x10): undefined reference to `typeinfo for mtm::Character'
/tmp/ccyu18Hf.o: In function `mtm::Character::Character(int, int, int, int, mtm::Team, mtm::CharacterType)':
/home/raghad-a/mtm3_3/Character.h:23: undefined reference to `vtable for mtm::Character'
collect2: error: ld returned 1 exit status

我在这个网站上查找了所有关于此类问题的问题,其中 none 解决了问题。

我使用狙击手的方式 std::shared_ptr<Sniper> ptr(new Sniper(health)); std::shared_ptr<Sniper> other_ptr(new Sniper(health));

我使用克隆的方式: ptr=static_cast<std::shared_ptr<Character>>(other_ptr->clone());

看起来你可能正在实例化一个抽象class(因为虚拟方法是纯虚拟的(=0))。

确保您正在动态实例化虚拟类型,而不是使用 new Character() - 因为那会命名抽象类型。

所以不要:

 Character x(.....);

也不要:

 Character x = Sniper(....); // slicing to abstract base

What is object slicing?

注意:

  • 你没有在构造函数中初始化teamempty也没有使用

工作样本:

Live On Coliru

using units_t = int;
enum class Team {team1};
enum class CharacterType {hulk};

#ifndef MTM_CHARACTER_H_
#define MTM_CHARACTER_H_
//#include "Exceptions.h"
//#include "Auxiliaries.h"
#include <memory>

namespace mtm {

    class Character {
        protected:
            units_t health;
            units_t ammo;
            units_t range;
            units_t power;
            Team team;
            CharacterType character_type;

        public:
            Character(units_t health, units_t ammo, units_t range, units_t power,
                    Team team, CharacterType type)
                : health(health), ammo(ammo), range(range), power(power),
                team(team), character_type(type) {}
            virtual Character* clone() const = 0;
            Character(const Character& character) = default;
    };
} // namespace mtm
#endif

#ifndef MTM_SNIPER_H_
#define MTM_SNIPER_H_
//#include "Character.h"
#include <memory>

namespace mtm {
    class Sniper : public Character {
        private:
            bool empty = false;
            units_t successful_attack = 0;

        public:
            Sniper(units_t health, units_t ammo, units_t range, units_t power,
                    Team team, CharacterType type, bool empty = false,
                    units_t successful_attack = 0)
                : Character(health, ammo, range, power, team, type),
                empty(empty), successful_attack(successful_attack) {}
            virtual Character* clone() const override { return new Sniper(*this); }
            Sniper(const Sniper& sniper) = default;
    };
} // namespace mtm
#endif

int main() {
    std::unique_ptr<mtm::Character> ch;
    ch = std::make_unique<mtm::Sniper>(1,1,1,1,Team::team1,CharacterType::hulk);
}