다음 클래스를 고려하십시오. (게임에서하지만 크게 단순화.)정적 생성자 초기화 프로그램이 가능합니까?
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;
(210)
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());
}
}
이 프로그램을 실행하면 당신은 그것이 작동하지 않는 것을 볼 것입니다. 몬스터의 건강은 감소해야하지만, 플레이어의 건강은 초기 값에 머물러 있습니다. 내가 생각하는 이유는 이것이다. 플레이어에는 정적 데이터 만 있습니다 (PlayerImpl _impl에 캡슐화 됨). 이것은 코드에서 다른 함수에서 호출 할 수있는 하나의 전역 Player 객체를 가질 수 있습니다. (monostate 패턴.)하지만 기본 클래스 인 Combat는 동적입니다. 그래서 플레이어 플레이어를 만들 때마다 그 일이 일어나고 있습니다. in fight() 실제로 Combat :: _ health가 기본값 인 새로운 Combat을 얻고 있습니다. 플레이어가 범위를 벗어나면 _health의 변경 사항이 모두 손실됩니다. 괴물에서는 몬스터 개체에도 동적 데이터가 있으므로 문제가되지 않습니다. 이상적으로 나는 말할 수있을 것이다.
class Player : public static Combat {
이 특정 전투에만 국한된다는 의미이지만 구문 오류이다. 그 일을하는 또 다른 방법이 있습니까? 아니면 구석에 그림을 그렸습니까?
** 너무 많은 코드. 이 부분을 좀 더 단순하게 만드십시오! –
왜 많은 플레이어 * 개체 *를 만드나요? 클래스 유형의 오브젝트는 클래스의 * 인스턴스 *입니다. 이 방법을 사용하면 모든 플레이어가 하나의 플레이어를 참조해야하는 많은 플레이어 개체를 만들 수 있습니다. 코드가 나타내는 것은 사용자의 의도/진행 상황과 모순됩니다. 플레이어 객체 (참조)를 모든 함수에 전달하거나 자유롭고 정적 인'getPlayer' 함수 ('Player '를 반환)를 사용하십시오. – dyp
@OliCharlesworth 예제 코드의 길이를 유감으로 생각합니다. 진짜는 훨씬 길어서 이것은 최소한으로 낮추었을 뿐이며 내 질문에 대한 충분한 맥락을 제공 할 수 있다고 생각했습니다. – Jaldhar