상속 및 사용자 인터페이스 디자인과 관련하여 질문이 있습니다. 상속 및 2 개의 인터페이스 유형
가 나는class Keyboardkey
의
벡터를 포함하는 class Keyboard
있는 등 Q, W, E, R, ... 같은 개별 키보드 키를 나타내는 class KeyboardKey
있다. [중요!]
저는 SFML을 사용하고 있으므로 이벤트 루프에서 이벤트가 생성 될 때마다 키보드 클래스로 보내집니다. 그런 다음이 클래스는 해당 이벤트를 해당 키로 만듭니다.
또한 KeyboardKey
을 상속받은 class SynthesizerKey
이 있습니다. "키 사용 가능", "키 누름"과 같은 일반 키 스터 외에도이 클래스에는 사인파 톤 생성을 처리하는 데 필요한 데이터와 함수가 포함되어 있습니다. 변수에는 sin 파의 진폭 및 현재 위상이 포함됩니다.
지금은 class SynthesizerKeyboard
을 만들려고합니다. 코드를 복사 할 때 좋은 프로그래밍 연습이 아니지만이 클래스에 class Keyboard
의 모든 코드를 복사하여 붙여 넣으 려하고있었습니다.
내가 가진 주된 문제는 SynthesizerKeyboard
에 버퍼에 저장할 샘플 시퀀스를 생성하는 기능이 있다는 것입니다. 샘플을 생성하기 위해 루프는 각 KeyboardKey
을 반복하고 누를 지 확인합니다. 그렇다면, 우리는 해당 키 노트/주파수에 해당하는 샘플을 생성해야합니다. 그러나
class KeyboardKey
는class SynthesizerKey
내가 벡터 요소의 멤버 데이터로서 죄 파의 위상 및 진폭에 대한 변수를 갖고 있지 아니 포함하기 때문이다. "리팩토링"[?]으로 알려진 것을 수행해야 할 수도 있고 부분에서 SynthesizerKey
의 "sin wave"부분을 분리해야한다고 생각합니다. 즉, 나는 SynthesizerKey
클래스를 버리고 Synthesizer
클래스와 KeyboardKey
클래스를 따로 가지고있다. 그런 다음 Synthesizer
의 벡터가 KeyboardKey
인 class Keyboard
에 SynthesizerKeyboard
에서 상속을 통해 액세스 할 수있는 것 이외에 class SynthesizerKeyboard
에 있습니다.
그러나 덜 우아합니다. 다른 방법이 있습니까?
다음은 독자가 quesiton을 더 자세히 이해하는 데 도움이되는 몇 가지 코드입니다.
SynthesizerKeyboard
class SynthesizerKeyboard : public Keyboard
{
public:
SynthesizerKeyboard(const sf::Font& sf_font)
: Keyboard(sf_font)
{
}
double Sample() const
{
for(std::vector<KeyboardKey>::iterator it = m_keyboardkey.begin()
it != m_keyboardkey.end(); ++ it)
{
if(it->IsKeyPressed())
{
it->Sample();
}
}
}
void GenerateBufferSamples(std::vector<sf::Int16> buffer)
{
for(std::size_t i = 0; i < buffer.size(); ++ i)
{
buffer[i] = Sample();
}
}
};
SynthesizerKey
class SynthesizerKey : public KeyboardKey
{
protected:
AbstractOscillator *m_abstractoscillator;
public:
double Sample() const
{
return m_abstractoscillator->Sample();
}
};
키보드
class Keyboard
{
protected:
std::vector<KeyboardKey> m_keyboardkey;
public:
Keyboard(const sf::Font& sf_font)
void Draw(sf::RenderWindow& window)
void Event(const sf::Event& event)
{
for(std::vector<KeyboardKey>::iterator it = m_keyboardkey.begin();
it != m_keyboardkey.end(); ++ it)
{
(*it).Event(event);
}
}
bool IsKeyPressed(const sf::Keyboard::Key& sf_key)
{
for(std::vector<KeyboardKey>::iterator it = m_keyboardkey.begin();
it != m_keyboardkey.end(); ++ it)
{
if((*it).Key() == sf_key)
{
return (*it).IsKeyPressed();
}
}
}
};
KeyboardKey
class KeyboardKey
{
protected:
KeyState m_keystate;
sf::Color m_pressed_color;
sf::Color m_release_color;
sf::Text m_sf_text;
sf::Keyboard::Key m_sf_keyboard_key;
sf::RectangleShape m_sf_rectangle;
public:
KeyboardKey(const sf::Keyboard::Key& sf_keyboard_key, const std::string& text, const sf::Font& sf_font,
const double position_x, const double position_y)
void Draw(sf::RenderWindow& window)
void Event(const sf::Event& event)
bool IsKeyPressed()
};
A는 당신이 복제에 대한 걱정 만들 수 'AbstractKeyboard'에서 'AbstractKeyboard'에서 호출되는'AbstractKeyboard'의 상속인에 의해 구현되는 순수 가상 특성화 함수로 완성됩니다. 예를 들어,'Moog' 특정 동작이 필요할 때.'AbstractKeyboard'는'Std :: vector>도 포함하고있어서'KeyboardKey' 또는 적절한 하위 클래스가 메모리 관리 문제없이 포함될 수 있습니다. –
user4581301
@ user4581301 나는 당신의 제안을 상세히 완전히 이해하고 있는지 잘 모르겠다.이 사실을 나에게 더 설명 할 수 있을지, 아니면 예를 들어 제안 된 답변을 추가 할 수 있을까? – user3728501