簡體   English   中英

如何避免此丑陋的嵌套類C ++代碼

[英]How can I avoid this ugly nested class c++ code

我用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類中。 我寧願重新組織一切並擁有更好的設計。

您有更好的設計建議嗎?

將您的各種類組織到一個namespace以將它們分組,而不是單個類。 一旦增長,這個東西將變得很難維護。 您想使用類來封裝功能,並為“外部世界”提供一個簡單而全面的接口。 通常,每個類都會獲得自己的頭文件( .h.hpp )和編譯單元( .cpp )。

接受使用getter和setter函數有許多充分的理由 -它們是良好封裝的基礎。 如果確實需要,則始終可以在嵌套類中使用friend class Audio來使private成員和protected成員對Audio可見,但對項目中可能(在將來的某個時候)包括這些成員的所有其他類不是可見的類。

您說您不喜歡編寫audio.setMusicVolume(0.8f)而不是audio.music.setMusicVolume(0.8f) 有人可能會說audio.getMusic().setVolume(0.8f)是一個很好的折衷方案,但Demeter不同意。 通過使用諸如setMusicVolume類的包裝函數,每個其他類僅需要了解Audio並與Audio通信,而Music嚴格是內部的,並且僅由Audio本身知道。 如果使用函數鏈接,則會失去此優勢,並將MusicSfx暴露給世界-這不一定是一件壞事。 如果您想堅持自己的語法,我的建議是使公共接口保持很小, 並在需要時使用friendAudio公開更多功能。

僅供參考,除了使用名稱空間外,嵌套類型還可以像成員函數一樣通過使用限定名稱來脫節放置。 因此,您可以執行以下操作:

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;
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM