2013-09-06 2 views
4

현재 재로드를위한 무기 클래스에 함수를 구현하는 방법에 대한 손실이 있습니다."재로드"기능 구현

내 프로그램은 (학습을 목적으로) 수행 할 것으로 예상되는 Weapon 클래스에는 Sword와 Crossbow라는 두 클래스가 있습니다. 소드 클래스는 예상대로 작동하기 때문에 함께 놀 필요가 있습니다. 그러나 Crossbow 클래스는로드 여부를 감지해야하며,로드되지 않으면로드하고 실행합니다. 예를 들어

, 여기 선생님이 클래스에 준 데모 출력 :

크로스 보우 15 손상 포인트를 입히고 (이 그것을보고 생각하는 방법이다).

소드는 10 포인트의 피해를 입 힙니다.

석궁이 없습니다!

크로스 보우는 15 점의 피해를 입 힙니다.

낙관적 인 말로하면, 나는 비슷하게 보이고 싶습니다.

제발, 직접적인 답변이 없습니다. 이것은 숙제이며, 저는 이것을 정말로 배우고 싶습니다. 나는 올바른 방향으로 점들을 찾고있다.

Weapon.h

#include <iostream> 

using namespace std; 

class Weapon 
{ 
public: 
    Weapon(int damage = 0); 
    virtual void Attack() const = 0; 

protected: 
    int m_Damage; 
}; 

Weapon::Weapon(int damage) : m_Damage(damage) 
{} 

class Sword : public Weapon 
{ 
public: 
    Sword(int damage = 10); 
    virtual void Attack() const; 
}; 

Sword::Sword(int damage): Weapon(damage) 
{} 

void Sword::Attack() const 
{ 
    cout << "The sword hits for " << m_Damage << " points of damage" << endl; 
} 

class Crossbow : public Weapon 
{ 
public: 
    Crossbow(int damage = 20); 
    virtual void Attack() const; 
      void Reload() const; 
}; 

Crossbow::Crossbow(int damage) : Weapon(damage) 
{} 

void Crossbow::Attack() const 
{ 
cout << "The crossbow hits for " << m_Damage << " points of damage" << endl; 
} 

void Crossbow::Reload() const 
{ 
cout << "Crossbow not loaded! Please reload" << endl; 
} 
+0

에헴 ... 그건 너무 많은 도움이됩니다.'Crossbow'는 내부 상태를 가지고 있으며 OO의 주요 기능 중 하나가 캡슐화되어 있기 때문에이 상태를 저장하는 위치는 분명해야합니다. –

+0

Reloadable 인터페이스를 만들 수도 있고 그것을 필요로하는 클래스에서만 구현하십시오. –

+0

@ HanletEscaño : C++에는 인터페이스가 없습니다. 서브 클래스 또는 mutliple 상속 (brrr)이 작업을 수행 할 수 있습니다. –

답변

2

Base 클래스에 "ammo"필드를 추가하지 마십시오. 칼에는 "탄약"이라는 개념이 없습니다. Crossbow 클래스에 추가하십시오. 플래그로 bool 유형이 될 수 있습니다.

생성자 초기 목록에 있도록하는 석궁을 만드는 동안이로드 아니에요 가정 할 수있다, 당신은 단지 추가로드 (false)를

그럼 당신은 처음로드하는 경우 확인하여 "공격"을 변경해야합니다. 당신의 공격이 작업을 수행하는

void Crossbow::reload() { 
    if (!loaded) { 
     cout << "Crossbow loading ..." << endl; 
     loaded = true; 
    } 
    cout << "Crossbow reloaded" << endl; 
} 

void Crossbow::attack() { 
    if (!loaded) { 
     cout << "Crossbow not loaded! Please reload" << endl; 
     reload(); 
    } 
    cout << "The crossbow hits for " << m_Damage << " points of damage" << endl; 
    loaded = false; 
} 

및 기능 변경 값이 있기 때문에 const를 할 수 없습니다 다시로드 :로드되지 않은 경우, 재 장전 기능의 첫 번째 종류를 다시로드합니다.

이제는 다시로드하기 위해 reload()를 호출하거나로드 여부에 관계없이 attack()을 호출 할 수 있습니다.

+0

이것은 내 말에 반대하지만 "직접 대답을 부탁해주십시오."이것은 내가 이미 내 머리 속에 가지고있는 생각을 확인한 것입니다. –

2

당신을 맞는, 그러나 ammo 같은 Weapon라는 뭔가에 필드를 추가하려고하면 확실하지. 생성자는이를 필요한 양으로 설정하고 석궁의 Attack은 떨림에 남아있는 탄약이 있는지 확인해야합니다. 그렇지 않은 경우 ammo의 값을 원본으로 설정하십시오. 이것은 정말 간단합니다. Sword의 경우 간단히 탄환을 확인하지 마십시오! :)

또한 이러한 개념을 잘 이해할 때까지는 나쁜 습관이며 일시적인 수정 사항입니다. 올바른 방법은 Weapon에서 상속받은 새 클래스를 만드는 것이며이 클래스는 탄창이있는 무기에 상속됩니다.

희망, 도와 주신 재미 있고 C++을 배우십시오! :)

+0

나는 동의하지 않을 .. superfluo 기본 클래스에 필드 추가 파생 된 클래스 중 일부에 대한 우리는 최선의 방법이 아닙니다. IMHO 탄약을 필요로하는 무기에 대한 또 다른 추상화 수준이 필요합니다. 마찬가지로 칼은 클럽과 구별하기 위해 날카로운 무기라고 주장하는 것으로부터 도출 될 수 있습니다. –

+0

예, 실제로 나쁜 습관입니다. 그러나 OP는 학습자이며 또 다른 깊이의 층을 추가하는 것은 그를위한 과잉 공격 일 수 있습니다. 이것은 내가 내 대답을 쓴 유일한 이유입니다. –

+0

이것은 빨간 청어입니다. 문제는 탄약에 관한 것이 아닙니다 (아직). –