虚函数不起作用

Virtual function don't work

此代码未编译。基本class.

中虚函数attack()的所有问题

在class团队中没有访问massive的权限。我正在尝试做这些 classes friend.But 它不管用。我也完成了 function ptr 但它不起作用。

虚函数在继承的 classes 中也不起作用。 Visual studio 2015 显示错误:

C2228, C2227, C2027.

请帮忙。

class Team;
class Unit
{
 protected:
int hp;
int dmg;
int doodge;
 public:
Unit(int hp, int dmg, int doodge): hp(hp), dmg(dmg), doodge(doodge){}
int GetHP()
{
    return hp;
}
void SetHP(int hp)
{
    this->hp = hp;
}
virtual void attack(Team &T)
{
    int id = rand() % 3;
    for (int i = 0; i < 3; i++)
        if (typeid(*this) == typeid(T.arr[i]))
        {
            id = i;
            break;
        }
    if (T.arr[id] <= 0)
        return;
    else
        T.arr[id]->SetHP(T.arr[id]->GetHP() - this->dmg);
 }
};
class Swordsman:public Unit
{
 public:
Swordsman():Unit(15,5,60){}
//virtual void attack(Team & T)override
//{
//  int id = rand() % 3;
//  for (int i = 0; i < 3; i++)
//      if (typeid(Swordsman) == typeid())
//      {
//          id = i;
//          break;
//      }
//  if (*T.arr[id]->GetHP <= 0)
//      return;
//  else
//      *T.arr[id]->SetHP(T.arr[id]->GetHP() - dmg);
//}
};
class Archer :public Unit
{
public:
Archer() :Unit(12, 4, 40) {}
//virtual void attack(Team & T)override
//{
//  int id = rand() % 3;
//  for (int i = 0; i < 3; i++)
//      if (typeid(Archer) == typeid())
//      {
//          id = i;
//          break;
//      }
//  if (*T.arr[id]->GetHP <= 0)
//      return;
//  else
//      *T.arr[id]->SetHP(T.arr[id]->GetHP() - dmg);
//}
};
class Mage :public Unit
{
 public:
Mage() :Unit(8, 10, 30) {}
/*virtual void attack(Team & T)override
{
    int id = rand() % 3;
    for (int i = 0; i < 3; i++)
        if (typeid(*this) == typeid())
        {
            id = i;
            break;
        }*/
};
class Team
{
static short counter;
string name;
Unit* arr[3];
public:
Team()
{
    name = "Team " + counter++;
    for (int i = 0; i < 3; i++)
    {
        int selecter = rand() % 3;
        switch (selecter)
        {
        case 0:
            arr[i] = new Swordsman();
            break;
        case 1:
            arr[i] = new Archer();
            break;
        case 2:
            arr[i] = new Mage();
            break;
        }
    }
}
~Team()
{
    delete[]arr;
}
Unit * ptr(int id)
{
    return arr[id];
}
bool check()
{
    bool res = false;
    for (int i = 0; i < 3; i++)
        if (arr[i]->GetHP() > 0)
            res = true;
    return res;
}
void print()
{
    cout << endl << "\t\t" << name << endl << endl;
    cout << "\t" << typeid(*arr[0]).name() << endl;
    cout << "\t" << typeid(*arr[1]).name() << endl;
    cout << "\t" << typeid(*arr[2]).name() << endl;
}
friend class Unit;
};
short Team::counter = 0;
class Game
{
Team A, B;
public:
int Play()
{
    while (true)
    {
        A.ptr(1)->attack(B);
        if (A.check())
            return 1;
        else if (B.check())
            return 2;

    }
 }
};
int main()
{
       return 0;
}

省略任何不相关的内容:

class Team;
class Unit
{
public:
    virtual void attack(Team &T)
    {
        if(typeid(*this) == typeid(T.arr[i]))
        //                           ^^^
        { }
    }
};

您正在访问 class Team 的成员,但在给定的时间,您只提供了 Team 的声明...旁注:这不是特定的到虚函数,但会出现在 任何 你写的代码中。

您现在的问题是 classes TeamUnit 的函数实现都依赖于另一个 class 的完整定义。所以解决问题的唯一方法是实现 class 之外的功能之一,e。 g.:

class Team;
class Unit
{
public:
    // requires Team, so only declared, not implemented!
    virtual void attack(Team &T);
    //                          ^
};

class Team
{
    // complete definition!
};

void Unit::attack(Team& t)
{
    // now implementation of...
}

另一个小问题是 arr 成员是私有的。嗯,你已经提供了一个 getter (ptr),所以使用它(并给它一个更好的名字......)。

如果您想进一步实现简洁的设计,请将您的单元和团队分成不同的编译单元,每个编译单元都带有一个 header 和一个源文件:

unit.h:

class Team;
class Unit
{
    // private members
public:
    // only declarations as above, including constructor/destructor
    // by the way: you are lacking a virtual destructor!!!
    virtual ~Unit();
};

unit.cpp:

#include "unit.h"
#include "team.h" // fetch the definition of Team!

Unit(/*...*/) { }
Unit::~Unit() { }
// function definitions as shown above...

你会为 Team 甚至你的 Unit 派生的 classes 以及 Game class 做同样的事情。但是请注意,如果要继承,则需要完整的 class 定义,因此您需要在 headers:

中包含 unit.h

archer.h:

#include "unit.h"

class Archer : public Unit
{
    // again, only function declarations...
    // as base class has already a virtual destructor, own destructor
    // gets virtual implicitly (even the default one), so if you do
    // not need it, you do not have to define it...
};

archer.cpp:

#include "archer.h"
// and whatever else needed, solely, unit.h already comes with archer.h

// implementations...