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() 函数需要全部填充它们。这被认为是不好的,因为如果有人从派生类派生类,它可能会破坏封装。解决这个问题的正确方法是什么?我已经发现使用 getter/setter 也被认为是不好的。

非常感谢任何花时间阅读本文的人:)

4

1 回答 1

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

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

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

于 2012-04-08T23:40:48.743 回答