我用SDL用C ++编写游戏。我用C语言写了一年多的游戏,现在我在过去的7个月里一直用C ++写作。我试图避免几乎所有的全局变量并转移到所有权系统,其中每个对象都由其他东西拥有。这样我就可以管理拥有shared_ptr成员的类的生活,几乎从不担心释放指针。
例如,我的游戏是一个带有子系统的类。
class Game
{
public:
Game();
~Game();
void runFrame();
std::shared_ptr<Display> display;
std::shared_ptr<Audio> audio;
std::shared_ptr<Save> save;
};
但是我遇到了乱看的嵌套类,比如下面的音频类。
class Audio
{
public:
Audio(Game& parent);
~Audio();
struct MusicFiles;
struct SfxFiles;
std::shared_ptr<MusicFiles> musicFiles;
std::shared_ptr<SfxFiles> sfxFiles;
private:
class Music
{
public:
class File
{
public:
File(Music& parent, std::string fileAddr);
~File();
void play();
void fadeIn();
void stop();
private:
Music& _parent;
std::string addr;
Mix_Music* chunk;
};
Music(Audio& parent);
~Music();
void setVolume();
private:
Audio& _parent;
bool _enabled;
int _volume;
};
class Sfx
{
public:
class File
{
public:
File(Sfx& parent, std::string fileAddr);
~File();
void play();
void stop();
private:
Sfx& _parent;
std::string addr;
Mix_Chunk* chunk;
int channel;
};
Sfx(Audio& parent);
~Sfx();
void setVolume();
private:
Audio& _parent;
bool _enabled;
int _volume;
};
Game& _parent;
Music _music;
Sfx _sfx;
};
我有嵌套类,因为我不喜欢在每个函数名中写“Music”或“Sfx”,如setMusicVolume(),setSfxVolume(),setMusicHook(),setSfxHook()等。 我可以拉出嵌套类,但Music和Sfx只需要存在于Audio类中。我宁愿重组一切,也有更好的设计。
你有更好的设计建议吗?
答案 0 :(得分:3)
将您的各种课程组织成namespace
以对其进行分组,而不是将其分组。一旦它成长,这个东西将变得非常难以维持。您希望使用您的类来封装功能,并为“外部世界”提供简单而全面的界面。通常,每个类都将获得自己的头文件(.h
或.hpp
)和编译单元(.cpp
)。
接受使用getter和setter函数many good reasons - 它们是良好封装的基础。如果您真的需要,可以始终在嵌套类中使用friend class Audio
,使private
和protected
成员对Audio
可见,但不能对项目中的所有其他类可见可能(在未来的某个时间,可能)包括这些类。
你说你不喜欢写audio.setMusicVolume(0.8f)
而不是audio.music.setMusicVolume(0.8f)
。有人可能会说audio.getMusic().setVolume(0.8f)
是一个很好的妥协,但Demeter不同意。通过使用诸如setMusicVolume
之类的包装函数,每个其他类只需要了解Audio
并与Music
进行通信,而Audio
是严格内部的,并且只有Music
本身知道。如果你使用函数链,你会失去这个优势,并向世界展示Sfx
和Audio
- 这不一定是坏事。如果你想坚持你的语法,我的建议是保持公共接口非常小and use friend
,以便在需要时向{{1}}公开更多功能。
答案 1 :(得分:1)
仅供参考,除了使用命名空间之外,嵌套类型可以通过使用其限定名称放置在行外,就像成员函数一样。所以你可以这样做:
class Audio
{
public:
Audio(Game& parent);
~Audio();
struct MusicFiles;
struct SfxFiles;
std::shared_ptr<MusicFiles> musicFiles;
std::shared_ptr<SfxFiles> sfxFiles;
private:
class Music;
};
在另一个档案中
#include "Audio.h"
class Audio::Music
{
public:
class File;
Music(Audio& parent);
~Music();
void setVolume();
private:
Audio& _parent;
bool _enabled;
int _volume;
};