2012-04-08 64 views
0

似乎普遍認爲使用受保護數據成員是一個壞主意。我想知道在一個特定的情況下會有什麼好的選擇。受保護數據成員的替代方案,具體案例研究

以下面的課程叫做CModule,它代表一個音頻模塊(Amiga風格的跟蹤音樂)。存在許多不同的模塊格式,但它們之間唯一的區別在於文件格式(加載)和音頻效果處理。 CModule擁有所有通用功能,派生類爲每種特定格式實現加載和效果。

class CModule 
{ 
public: 
     CModule(string Filename); //Song file name to load. 

     //Common methods... 
     void Play(); 
     void Stop(); //Etc... 

protected: 

     //Derived class should implement these with format specific code. 
     //Base class code calls these when needed. 
     virtual void Load()=0; 
     virtual void Effects()=0; 

     //Song information/data. 
     vector<CInstrument> Instruments; 
     vector<CPattern> Patterns; 
     //And much, MUCH more... 
}; 

由於派生類的Load()函數需要填充它們,所以幾乎所有的數據成員都受到保護。這被認爲是不好的,因爲如果有人從派生類派生類,它可以破壞封裝。解決這個問題的正確方法是什麼?我已經發現使用getters/setters也被認爲是不好的。

非常感謝任何人都抽出時間來閱讀這篇:)

回答

0

沒有什麼錯誤使用受保護的數據成員,如果使用私有不會爲您的解決方案工作,使用公共數據成員卻幾乎從來沒有一個好主意(但有時也可以)。

在這種情況下,我可能會讓你的矢量爲私有,但只需創建getter和setter方法。沿線的東西:

class CModule 
{ 
public: 
     CModule(string Filename); //Song file name to load. 

     //Common methods... 
     void Play(); 
     void Stop(); //Etc... 

protected: 

     //Derived class should implement these with format specific code. 
     //Base class code calls these when needed. 
     virtual void Load()=0; 
     virtual void Effects()=0; 

     void AddInstrument(CInstrument instrument) 
     { 
      Instruments.push_back(instrument); 
     } 

     Instrument GetInstrument(int index) 
     { 
      return Instruments[index]; 
     } 

     int InstrumentCount() 
     { 
      return Instruments.size(); 
     } 
private: 
     //Song information/data. 
     vector<CInstrument> Instruments; 
     vector<CPattern> Patterns; 
     //And much, MUCH more... 
}; 

這是一個剛開始的樂器,你也必須採取類似的方法與模式。或者,你也可以傳回載體,但這是更加封裝一點。

另外請注意,我正在做這個關閉我的頭頂,並沒有測試它反對任何錯別字,但希望它傳達的想法。