考虑以下类别。 (从一个游戏,但极大地简化了。)是否可以使用静态构造函数初始化程序?
combat.h:
class Combat {
public:
Combat();
Combat(int health, int offense, int defense);
virtual ~Combat();
int attack();
int defend();
int health() const;
void setHealth(int health);
private:
struct CombatImpl;
std::unique_ptr<CombatImpl> _impl;
};
combat.cc:
struct Combat::CombatImpl {
CombatImpl();
CombatImpl(int health, int offense, int defense);
~CombatImpl()=default;
int _health;
int _offense;
int _defense;
};
Combat::Combat(int health, int offense, int defense) :
_impl { new Combat::CombatImpl(health, offense, defense) } {
}
Combat::~Combat()=default;
int Combat::attack() {
int hits = 0;
for(int i = 0; i < _impl->_offense; i++) {
if (rand() % 6 == 5) {
hits++;
}
}
return hits;
}
int Combat::defend() {
int parries = 0;
for(int i = 0; i < _impl->_defense; i++) {
if (rand() % 6 == 5) {
parries++;
}
}
return parries;
}
int Combat::health() const {
return _impl->_health;
}
void Combat::setHealth(int health) {
_impl->_health += health;
}
Combat::CombatImpl::CombatImpl(int health, int offense, int defense) {
_health = health;
_offense = offense;
_defense = defense;
}
monster.h:
class Monster: public Combat {
public:
Monster(int health, int offense, int defense);
virtual ~Monster();
}
monster.cc:
Monster::Monster(int health, int offense, int defense)
: Combat(health, offense, defense) {}
Monster::~Monster()=default;
个
player.h:
class Player : public Combat {
public:
Player();
virtual ~Player();
private:
struct PlayerImpl;
static PlayerImpl _impl;
};
player.cc:
struct Player::PlayerImpl {
PlayerImpl()=default;
~PlayerImpl()=default;
} Player::_impl;
Player::Player() : Combat(17, 1, 1) {
}
Player::~Player()=default;
...最后,测试程序使用它们:
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <memory>
using namespace std;
#include "monster.h"
#include "player.h"
static Monster monster(3, 1, 1);
void fight() {
Player player;
int damage = monster.attack();
damage -= player.defend();
if (damage > 0) {
player.setHealth(-damage);
}
if (player.health() < 1) {
return;
}
damage = player.attack();
damage -= monster.defend();
if (damage > 0) {
monster.setHealth(-damage);
}
if (monster.health() < 1) {
return;
}
}
int main() {
Player player;
srand(time(NULL));
while (player.health() > 0 && monster.health() > 0) {
fight();
printf("player health = %d monster health = %d\n", player.health(),
monster.health());
}
}
如果你运行这个程序你会看到它不起作用。怪兽的健康状况应该会降低,但是玩家的健康状况会停留在初始值。我认为这是发生的原因是这样的; Player只有静态数据(封装在PlayerImpl _impl中)这样我就可以拥有一个全局Player对象,我可以从我的代码中的不同函数中调用它。 (单稳态模式)。但其基类Combat是动态的。所以发生的是每次我创建Player播放器;在战斗()我实际上得到一个新的战斗,其中战斗:: _健康是默认值。当玩家超出范围时,_health的任何更改都将丢失。在怪物中,这不是问题,因为怪物对象也有动态数据。理想情况下,我可以说
class Player : public static Combat {
意思是使静态这个特定的战斗,但这是一个语法错误。有没有另外一种方法呢?还是我把自己画在一个角落?
**远**代码太多。请简化这一些更多! –
为什么你创造了很多玩家*对象*?一个对象(类类型)是一个类的*实例*。通过使用这种方法,创建许多玩家对象,所有玩家都应引用一名玩家,您的代码表明与您的意图/发生的事情相矛盾。将播放器对象(引用)传递给每个函数,或者使用自由/静态的'getPlayer'函数(返回'Player&')。 – dyp
@OliCharlesworth对不起,关于示例代码的长度。真实情况要长得多,而且这是我认为可以削减的最低限度,并且仍然为我的问题提供了足够的背景。 – Jaldhar