我有一個關於繼承和設計用戶界面的問題。繼承和2接口類型
我有一個class KeyboardKey
其中表示單獨的鍵盤的鍵,如Q,W,E,R,...等
我有一個class Keyboard
其中包含的class Keyboardkey
一個矢量。 [重要!]
我正在使用SFML,所以每次從事件循環中生成事件時,都會將它發送到鍵盤類。然後這個類將這個事件傳遞給相應的鍵。
另外,我有一個class SynthesizerKey
繼承自KeyboardKey
。除了常規關鍵的東西,例如「是關鍵啓用」,「關鍵是關鍵」之外,該類還包含用於處理產生正弦波音的數據和函數。變量包括正弦波的幅度和電流相位。
我現在要創建一個class SynthesizerKeyboard
。我正要將class Keyboard
中的所有代碼複製並粘貼到這個類中,但這不是很好的編程習慣,因爲代碼是重複的!
我遇到的主要問題是SynthesizerKeyboard
包含一個函數,用於生成要存儲在緩衝區中的樣本序列。爲了生成樣本,循環遍歷每個KeyboardKey
並檢查它是否被按下。如果是,那麼我們必須生成一個對應於該鍵音符/頻率的樣本。
然而,由於載體含有class KeyboardKey
和不class SynthesizerKey
我沒有對作爲向量元素的構件數據罪波的相位和振幅的變量。
我想我可能不得不做所謂的「重構」[?],並將SynthesizerKey
的「正弦波」部分與KeyboardKey
部分分開。換句話說,我分開了SynthesizerKey
類,並且有一個Synthesizer
類和一個KeyboardKey
類。然後,我在class SynthesizerKeyboard
中有一個Synthesizer
的矢量,此外還有KeyboardKey
的矢量class Keyboard
,我可以通過繼承訪問SynthesizerKeyboard
。
但是這不太優雅。有另一種方法嗎?
下面是一些代碼,可以幫助讀者更詳細地瞭解問題。
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()
};
您可以劃分的代碼你擔心複製在'AbstractKeyboard'中完成了由'AbstractKeyboard'的繼承者實現的純虛擬專用函數,例如,當需要'Moog'特定的行爲時,將從'AbstractKeyboard'調用。'AbstractKeyboard'還包含'std :: vector>',這樣'KeyboardKey'或者適當的子類就可以被包含而沒有內存管理問題。 –
user4581301
@ user4581301我不確定我是否完全理解了您的建議,可以向我進一步解釋這個問題,或者可以添加一個建議的答案,或者添加一個示例? – user3728501