似乎普遍认为使用受保护的数据成员是一个坏主意。我想知道在特定情况下有什么好的选择。
采用以下名为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()函数需要填充它们。这被认为是不好的,因为如果有人从派生类派生一个类,它可能会破坏封装。解决这个问题的正确方法是什么?我已经发现使用getter / setter也被认为是坏事。
非常感谢任何花时间阅读此内容的人:)
答案 0 :(得分: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...
};
这只是乐器的开始,你也必须对模式采取类似的方法。或者你也可以只传回向量,但这有点封装。
另请注意,我正在做这件事,并没有对任何错别字的测试进行测试,但希望它传达了这个想法。