Could someone explain this 'protected virtuals' vs. 'public virtuals' comparison?
<p>The question is from c++ faq.</p>

<p><a href="http://www.parashift.com/c++-faq-lite/protected-virtuals.html" rel="nofollow">http://www.parashift.com/c++-faq-lite/protected-virtuals.html</a></p>

<p>Code using public overloaded virtuals:</p>

<pre><code>class Base {
public:
  virtual void f(int x);    ← may or may not be pure virtual
  virtual void f(double x); ← may or may not be pure virtual
};
</code></pre>

<p>Improving this via the Public Overloaded Non-Virtuals Call Protected Non-Overloaded Virtuals idiom:</p>

<pre><code>class Base {
public:
  void f(int x)    { f_int(x); }  ← non-virtual
  void f(double x) { f_dbl(x); }  ← non-virtual
protected:
  virtual void f_int(int);
  virtual void f_dbl(double);
};
</code></pre>

<p>The author said, 'The idea of the Public Overloaded Non-Virtuals Call Protected Non-Overloaded Virtuals idiom is to change the public overloaded methods to non-virtuals, and make those call protected non-overloaded virtuals.'</p>

<p>But i do not understand what the author said on how this idiom improve risk:</p>

<p>' the idiom packs the complexity of properly managing the hiding rule into the base class (singular). This means the derived classes (plural) more-or-less automatically handle the hiding rule, so the various developers who produce those derived classes can remain almost completely focused on the details of the derived classes themselves — they need not concern themselves with the (subtle and often misunderstood) hiding rule. This greatly reduces the chance that the writers of the derived classes will screw up the hiding-rule. '</p>

<p>Why does this solve the hiding problem? From what i understand, name hiding has nothing to do whether the member function is 'virtual' or not. If a derived class of 'base' rewrites a function f(), it will still hide the f(int) and f(double), right?</p>

<p>From this idiom all i can see is that author change the 'base' virtual f() to non virtual, and put helper functions f_int(), f_dbl() in 'protected virtual', like the name of idiom said. It does nothing good yet but in contrary eliminates possibility of dynamic binding from base class pointer/reference. What is the true benefit of this idiom?</p>

<p>Any one could help? Thanks.</p>

<p>Hi, Kerrek</p>

<p>Are you saying this? I do not fully understand the 2nd paragraph of your answer. Could you give an example?</p>

<pre><code>class base {
public: 
    virtual void f(int x);
    virtual void f(double x);
}

class derived : public base {
public:
    virtual int f(int x); // oops, will hide base::f(int x) AND base::f(double x)
}

base *bp = new base();
base *dp = new derived();
bp-&gt;f(int i);    // ok
dp-&gt;f(int i);    // surprise!
dp-&gt;f(double d); // compile error!


class Base {
public:
    void f(int x)    { f_int(x); }  
    void f(double x) { f_dbl(x); } 
protected:
    virtual void f_int(int);
    virtual void f_dbl(double);
};

class derived : public base {
public:
    // nothing to override here 'cause f() is non virtual
protected:
    // because f_int() and f_dbl are unique names, override or hide f_int() will not affect f_dbl()?
    virtual int f_int(int);  // oops, will hide base::f(int x), but developer may want this on purpose
                             // no effect on f_dbl(), which is good
}

base bobj;
derived dobj;
bobj.f(int i);    // ok
dobj.f(double d); // ok
</code></pre>
