受保护数据成员的替代方案,具体案例研究

时间:2012-04-08 23:29:14

标签: c++ protected data-members

似乎普遍认为使用受保护的数据成员是一个坏主意。我想知道在特定情况下有什么好的选择。

采用以下名为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也被认为是坏事。

非常感谢任何花时间阅读此内容的人:)

1 个答案:

答案 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...
};

这只是乐器的开始,你也必须对模式采取类似的方法。或者你也可以只传回向量,但这有点封装。

另请注意,我正在做这件事,并没有对任何错别字的测试进行测试,但希望它传达了这个想法。