`std::shared_ptr`:不是参数 _Ty 的有效模板类型参数

`std::shared_ptr`: is not a valid template type argument for parameter `_Ty`

错误

Hero: 未声明的标识符

std::shared_ptr: Hero 不是参数 _Ty

的有效模板类型参数

unary ->: std::shared_ptr 未定义此运算符或转换为预定义运算符可接受的类型

attackInput, getSkill os 不是 std::shared_ptr

的成员

void my::Weapon::hit(std::shared_ptr,std::shared_ptr):无法将参数 1 从 std::shard_ptr<my::Hero> 转换为 std::shared_ptr

Source.cpp

#include <iostream>
#include <cstdlib>
#include <time.h>
#include <windows.h>
#include "Hero.h"

void checkLife(my::Hero* hero)
{
    if (hero->is_dead())
    {
        delete hero;
        hero = nullptr;
    }
    if (hero == nullptr)
    {
        srand(time(0));
        int rand = 1 + std::rand() % 40;

        if (rand > 0 && rand <= 10) hero = new my::King();
        else if (rand > 10 && rand <= 20) hero = new my::Queen();
        else if (rand > 20 && rand <= 30) hero = new my::Troll();
        else if (rand > 30 && rand <= 40) hero = new my::Knight();
    }
}

int main()
{
    my::Hero* hero = nullptr;
    my::Hero* enemy = nullptr;

    while (true)
    {
        checkLife(hero);
        checkLife(enemy);

        hero->attackOutput(std::shared_ptr<my::Hero>(enemy));
        enemy->attackOutput(std::shared_ptr<my::Hero>(hero));

        system("cls");
        std::cout << hero->getName() << "`s health - " << hero->getHealth() << std::endl;
        std::cout << hero->getName() << "`s health - " << hero->getHealth() << std::endl;
        Sleep(1000);
    }

    if (hero != nullptr) delete hero;
    if (enemy != nullptr) delete enemy;
    system("pause");
    return 0;
} 

Hero.h

#pragma once
#include <memory>
#include <cstdlib>
#include <time.h>
#include <string>
#include "Weapon.h"

namespace my
{
    class Hero abstract
    {
    protected:
        std::shared_ptr<Weapon> weapon;
        std::string name;
        int health;
        int skill;
        int pressure;
        int nobleness;
        int beauty;

        virtual void attack(int damage)
        {
            srand(time(0));
            this->health -= damage + rand() % 20 - this->getPressurel();
        }
    public:
        Hero(std::string name, int health, int skill, int pressure, int nobleness, int beauty)
        {
            this->name = name;
            this->health = health;
            this->skill = skill;
            this->pressure = pressure;
            this->nobleness = nobleness;
            this->beauty = beauty;
        }
        std::string getName() const
        {
            return this->name;
        }
        int getHealth() const
        {
            return this->health;
        }
        int getSkill() const
        {
            return this->skill;
        }
        int getPressurel() const
        {
            return this->pressure;
        }
        int getNobleness() const
        {
            return this->nobleness;
        }
        int getBeauty() const
        {
            return this->beauty;
        }
        void attackInput(const int damage)
        {
            this->attack(damage);
        }
        void attackOutput(std::shared_ptr<Hero> enemy)
        {
            std::shared_ptr<Hero> thisHero(this);
            this->weapon->hit(std::shared_ptr<Hero>(thisHero), enemy);

        }
        virtual void takeWeapon(std::shared_ptr<Weapon> weapon)
        {
            this->weapon = weapon;
        }
        bool is_dead()
        {
            if (this->health <= 0) return true;
            else return false;
        }
    };

    class King : public Hero
    {
    public:
        King() : Hero("King", 300, 2, 4, 10, 15) {}
    };

    class Queen : public Hero
    {
    public:
        Queen() : Hero("Queen", 300, 2, 4, 10, 15) {}
    };

    class Troll : public Hero
    {
    public:
        Troll() : Hero("Troll", 300, 2, 4, 10, 15) {}
    };

    class Knight : public Hero
    {
    public:
        Knight() : Hero("Knight", 300, 2, 4, 10, 15) {}
    };
}

Weapon.h

#pragma once
#include "Hero.h"

namespace my
{
    class Weapon abstract
    {
    protected:
        const int damage;
        int wear;
    public:
        Weapon(int damage, int weight, int size, int wear) : damage(damage)
        {
            this->wear = wear;
        }
        Weapon() : Weapon(1, 1, 1, 1) {}

        virtual void setWeaponWear(int wear)
        {
            this->wear = wear;
        }
        virtual int getWeaponDamage() const
        {
            return this->damage;
        }
        virtual int getWeaponWear() const
        {
            return this->wear;
        }

        virtual void hit(std::shared_ptr<Hero> me, std::shared_ptr<Hero> enemy) = 0;
    };

    class Knife : public Weapon // NOZH
    {
    protected:
    public:
        virtual void hit(std::shared_ptr<Hero> me, std::shared_ptr<Hero> enemy)
        {
            int damage = this->damage * me->getBeauty();
            this->wear--;
            enemy->attackInput(damage);
        }
    };

    class Bow : public Weapon // LUCK
    {
    protected:
    public:
        virtual void hit(std::shared_ptr<Hero> me, std::shared_ptr<Hero> enemy)
        {
            int damage = this->damage * me->getNobleness();
            this->wear--;
            enemy->attackInput(damage);
        }
    };

    class Ax : public Weapon // TOPOR
    {
    protected:
    public:
        virtual void hit(std::shared_ptr<Hero> me, std::shared_ptr<Hero> enemy)
        {
            int damage = this->damage * me->getPressurel();
            this->wear--;
            enemy->attackInput(damage);
        }
    };

    class Sword : public Weapon // MECH
    {
    protected:
    public:
        virtual void hit(std::shared_ptr<Hero> me, std::shared_ptr<Hero> enemy)
        {
            int damage = this->damage * me->getSkill();
            this->wear--;
            enemy->attackInput(damage);
        }
    };
}

正如@WhozCraig 在评论中指出的,您存在循环依赖。 Hero.h 中需要 Weapon.hWeapon.h 中需要 Hero.h

你需要 Hero.hinWeapon.h. Is for thehit(...)function. The best solution would be to declare the hit function somewhere else. Right now the best place would be to add it to theHero 的唯一原因。一个英雄拥有武器并用该武器攻击另一个英雄,武器本身不能攻击,所以从语义上讲,在英雄内部使用 hit 函数更有意义 class.

您可以通过将代码拆分为头文件 (.h) 和源文件 (.cpp) 并在 Weaopon.h 中进行前向声明 Hero 来编译它。但这不会解决根本问题,设计仍然存在缺陷,如果扩展功能,可能会导致更多问题。