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

C++ 受保护数据成员的替代方案,具体案例研究,c++,protected,data-members,C++,Protected,Data Members,似乎普遍认为使用受保护的数据成员是个坏主意。我想知道在特定的情况下有什么好的选择 以下面名为CModule的类为例,它表示一个音频模块(Amiga风格的音乐跟踪器)。存在许多不同的模块格式,但它们之间的唯一区别在于文件格式(加载)和音频效果处理。CModule拥有所有的公共功能,派生类实现每个特定格式的加载和效果 class CModule { public: CModule(string Filename); //Song file name to load.

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

以下面名为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...
};
类CModule
{
公众:
CModule(字符串文件名);//要加载的歌曲文件名。
//常用方法。。。
无效播放();
void Stop();//等等。。。
受保护的:
//派生类应使用特定于格式的代码实现这些。
//基类代码在需要时调用这些函数。
虚空荷载()=0;
虚空效果()=0;
//歌曲信息/数据。
矢量仪器;
向量模式;
//还有更多。。。
};
几乎所有的数据成员都受到保护,因为派生类的Load()函数需要填充它们。这被认为是不好的,因为如果有人从派生类派生类,它会破坏封装。解决这个问题的正确方法是什么?我已经发现使用getter/setter也被认为是不好的


非常感谢所有花时间阅读本文的人:)

使用受保护的数据成员没有错如果使用private对您的解决方案不起作用,那么使用公共数据成员几乎从来都不是一个好主意(不过有时也可能是)

在本例中,我可能会将向量设置为私有的,但只需创建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...
};
类CModule
{
公众:
CModule(字符串文件名);//要加载的歌曲文件名。
//常用方法。。。
无效播放();
void Stop();//等等。。。
受保护的:
//派生类应使用特定于格式的代码实现这些。
//基类代码在需要时调用这些函数。
虚空荷载()=0;
虚空效果()=0;
无效附加仪器(仪器仪表)
{
仪器。推回(仪器);
}
仪表(int索引)
{
返回工具[指数];
}
int InstrumentCount()
{
返回仪器。尺寸();
}
私人:
//歌曲信息/数据。
矢量仪器;
向量模式;
//还有更多。。。
};
这只是仪器的一个开始,您还必须对模式采取类似的方法。或者你也可以把向量传回去,但这是一个稍微封装的过程

还要注意的是,我在做这件事的时候是头脑发热的,没有针对任何打字错误进行测试,但希望它能传达我的想法