函数指针作为参数

时间:2014-05-27 17:47:46

标签: c++ function pointers arguments

经过几个小时的搜索后,我仍然没有找到解决以下问题的方法。在我的游戏中,我使用了一个生成对象的抽象工厂。我正试图将这个工厂制造的功能传递给敌人。为此,我尝试使用一个函数指针,它指向factory-> getBullet()并使用敌人的构造函数传递它。它失败了:))

#include "Factory.h"
int main() 
{
    Factory* f = new Factory();
    f->getEnemy(&f->getBullet);
    return 0;
}

Factory.h

#include "Enemy.h";
#include "Bullet.h";
class Factory {
public:
    Factory();
    virtual ~Factory();
    Enemy* getEnemy(Bullet* (*getBulletPtr)(int));
    Bullet* getBullet(int damage);
};

Factory.cpp

#include "Factory.h"
Factory::Factory() {}
Factory::~Factory() {}

Enemy* Factory::getEnemy(Bullet* (*getBulletPtr)(int))
{return new Enemy(getBulletPtr);}

Bullet* Factory::getBullet(int damage)
{return new Bullet(damage);}

Enemy.h

#include "Bullet.h"
class Enemy
{
    private:
        Bullet* (*getBullet)(int) = NULL;
    public:
        Enemy(Bullet* (*getBulletPtr)(int));
        virtual ~Enemy();
};

Enemy.cpp

#include "Enemy.h"
Enemy::Enemy(Bullet* (*getBulletPtr)(int))
{
    getBullet = getBulletPtr;
    getBullet(10);
}

Enemy::~Enemy() {}

Bullet.h

#include <iostream>
using namespace std;

class Bullet {
public:
    Bullet(int damage);
    virtual ~Bullet();
};

Bullet.cpp

#include "Bullet.h"
Bullet::Bullet(int damage)
{
    cout << "This is a bullet: Damage:"<< damage << endl;
}

Bullet::~Bullet()
{}

当我尝试运行此代码时,出现以下错误:

ISO C++ forbids taking the address of a bound member function to form a pointer to member function.  Say '&Factory::getBullet' [-fpermissive]

当我改变

f->getEnemy(&f->getBullet);

f->getEnemy(&Factory::getBullet);

我收到以下错误:

no matching function for call to 'Factory::getEnemy(Bullet* (Factory::*)(int))'

如何将factory-&gt; getBullet函数传递给我的敌人。

任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:0)

我相信你的设计不好。通常,工厂会创建动态分配的对象的公共主题,并将基本指针返回给已分配的对象。

此外,大多数工厂根据某种输入创建对象,例如ID值或名称或类似的东西:

struct Shape
{
  virtual const std::string& what_am_i(void) = 0;
};  // Common base class for shapes.

struct Triangle : public Shape
{
  const std::string& what_am_i(void)
  {
     const static std::string name = "triangle";
  }
};

Shape * Shape_Factory(const std::string& shape_name)
{
  Shape * p_object = NULL;
  if (shape_name == "triangle")
  {
    p_object = new Triangle;
  }
  return p_object;
}

您可能不需要工厂来创建一个带子弹的敌人,您可以通过几个语句(清理您的代码)来执行此操作:

int main(void)
{
  Bullet  b_15(15);
  Enemy   e(b_15);
  return EXIT_SUCCESS;
}

上面的例子创造了一个15伤害子弹的敌人。这是一个不同于敌人受到15伤害子弹伤害的概念。

我建议应用这样的伤害:

struct Weapon
{
  virtual unsigned int get_damage(void) const = 0;
};

struct Bullet : public Weapon
{
  unsigned int get_damage(void) const
  { return 15;}
};

struct Player
{
  virtual void receive_damage(const Weapon& w) = 0;
};

struct Enemy : public Player
{
  unsigned int life_points;
  void receive_damage(const Weapon& w)
  {
    unsigned int damage = w.get_damage();
    if (life_points > damage)
    {
        life_points -= damage;
    }
    else
    {
        life_points = 0;
    }
};

int main(void)
{
  Bullet b;
  Enemy e;
  e.receive_damage(b);
  return EXIT_SUCCESS;
}

关于这个设计的一个好处是,你可以拿出来自Weapon的不同武器,如箭头,并告诉Enemy接受武器的伤害。

设计可以很好地扩展,以便任何Player(或派生自Player的类)都可以从Weapon派生的任何类中受到伤害。

另请注意,我没有使用动态分配,因此我没有任何内存泄漏问题。搜索你最喜欢的参考文献&#34;智能指针&#34;,&#34; unique_ptr&#34;或&#34; scoped_pointer&#34;。