今天,我注意到我基本上从不使用protected
C ++代码中的方法,因为我很少感到需要调用父级的非公共方法。我确实在模板方法模式中使用了Java中的protected,但是由于您可以在C ++中覆盖私有方法,因此我也不需要protected
。
那么,在哪些实际场景中我想protected
在C ++代码中使用方法?
(请注意,我一般不太喜欢实现继承,这可能会解释很多...)
今天,我注意到我基本上从不使用protected
C ++代码中的方法,因为我很少感到需要调用父级的非公共方法。我确实在模板方法模式中使用了Java中的protected,但是由于您可以在C ++中覆盖私有方法,因此我也不需要protected
。
那么,在哪些实际场景中我想protected
在C ++代码中使用方法?
(请注意,我一般不太喜欢实现继承,这可能会解释很多...)
Answers:
这是一个例子
class Base {
public:
// other members ...
protected:
~Base() { }
};
用作非多态基类。但是delete baseptr;
由于析构函数不可访问,因此不允许用户调用它。由于它没有虚拟析构函数,因此允许人们这样做将是不确定的行为。请参阅Herb的“虚拟性”。
我经常使用的一个示例是,在对象层次结构的基类中,我将有一个受保护的Logger。我所有的基类都需要访问Logger,但是没有理由使其可以公开访问。
另外,如果您使用的是Template模式,并且在基类上具有执行前或执行后的方法,则可能需要从重写方法中调用基本实现。如果基础仅是私有的(并且仍然可以用C ++覆盖),则将无法从覆盖方法调用基础实现。
只是我过去使用的一个示例。受保护的方法非常适合提供特定于实现的功能,同时还允许基类正确跟踪事物。考虑一个提供可重写的初始化函数的基类,但还必须具有确定是否初始化的状态:
class Base
{
private:
bool m_bInitialized;
public:
virtual void Initialize() = 0;
void setInitialized() { m_bInitialized = true; };
bool isInitialized() const { return m_bInitialized; };
}; // eo class Base
这里一切都很好。除非派生类不必费心调用setInitialized()
任何人都可以调用它的事实(我们可以在此将其设置为受保护的对象,以及使用受保护方法的另一个理由!)。我更喜欢使用虚拟受保护成员的类:
class Base
{
private:
bool m_bInitialized;
protected:
virtual void InitializeImpl() = 0;
public:
void Initialize()
{
InitializeImpl();
m_bInitialized = true;
}; // eo Initialize
bool isInitialized() const { return m_bInitialized; };
}; // eo class Base
在我们的新类中,所有初始化仍然委托给派生类。提供一个抛出的异常,我们维护我们的方法将要发生的“此类已初始化”协定。
也许这是不好的设计,但是我有这样的想法:
// much simplified, of course
class input_device // base class
{
public:
virtual ~input_device() {}
// normally would be private with public caller, etc.
virtual void update() = 0;
template <typename Func>
void register_callback(Func func)
{
mButtonPressSignal.connect(func);
}
protected:
void trigger_signal(unsigned button)
{
mButtonPressSignal(button);
}
private:
boost::signals2::signal<void(unsigned)> mButtonPressSignal;
};
in中的派生类update()
可以通过调用触发信号trigger_signal()
。但是因为这就是他们应该能够处理的信号,所以信号本身就被保密了。由于只有派生类才应该能够触发它,所以根本就什么都不能触发它,从而使触发函数受到保护。
“公共方法”:一个类可以做到这一点。“受保护的方法”:类如何做到这一点。“私有方法”:类如何做到这一点,但是“我很偏执,不想让任何人知道我如何做到这一点”。
// burguers.hpp
class BurguerClass {
private: void addSecretRecipeSauce();
protected: virtual void addBread();
protected: virtual void addSalad();
protected: virtual void addMeat();
protected: virtual void addExtraIngredients();
public: virtual void makeBurguer();
}
class CheeseBurguerClass: public BurguerClass {
protected: override void addBread();
protected: override void addSalad();
protected: override void addMeat();
protected: override void addExtraIngredients();
protected: virtual void addCheese();
public: override void makeBurguer();
}
class RanchStyleBurguerClass: public BurguerClass {
protected: override void addBread();
protected: override void addSalad();
protected: override void addMeat();
protected: override void addExtraIngredients();
public: override void makeBurguer();
}
class EastCoastVegetarianStyleBurguerClass: public BurguerClass {
protected: override void addBread();
protected: override void addSalad();
protected: override void addMeat();
protected: override void addExtraIngredients();
public: override void makeBurguer();
}
因此,一名新厨师(开发人员)到达了您的快餐店。您教书,卖汉堡包(公共方法),如何制作汉堡包(受保护的方法),但将“专利”秘密配方酱留给自己。