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

标签 c++ shared-ptr

错误

Hero :未声明的标识符

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

一元 -> :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

源.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) {}
    };
}

武器.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

您需要 Weapon.h 中的 Hero.h 的唯一原因。用于 hit(...) 函数。最好的解决方案是在其他地方声明 hit 函数。现在最好的地方是将其添加到 Hero 中。英雄拥有武器并用该武器攻击另一个英雄,武器本身无法攻击,因此仅从语义来看,在英雄类中拥有 hit 函数更有意义。

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

关于c++ - `std::shared_ptr` : is not a valid template type argument for parameter `_Ty` ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60001449/

相关文章:

c++ - 删除的函数在使用时带有编译时消息

c++ - 未解析的外部符号 __imp__wcsstr

iphone - Objective-C 和 C++ 中结构的大小

c++11 - C++ 在 std::shared_ptr<baseclass> 中使用派生类

c++ - 共享指针声明

c++ - 向下转换指向具有附加功能的派生类的共享指针 - 这安全吗?

c++ - 对 vector 进行排序 C++

c++ - 如何在 C++ 中分解指向成员的指针(获取类和成员类型)?

c++ - 共享指针引用

c++ - 检查 std::shared_ptr 中的空值