name hiding and fragile base problem

前端 未结 3 937
死守一世寂寞
死守一世寂寞 2020-12-03 14:41

I\'ve seen it stated that C++ has name hiding for the purposes of reducing the fragile base class problem. However, I definitely don\'t see how this helps. If the base class

3条回答
  •  一向
    一向 (楼主)
    2020-12-03 15:12

    In The Design and Evolution of C++, Bjarne Stroustrup Addison-Weslay, 1994 section 3.5.3 pp 77, 78, B.S. explains that the rule by which a name in a derived class hides all definition of the same name in its base classes is old and dates back from C with Classes. When it was introduced, B.S. considered it as the obvious consequence of scoping rules (it's the same for nested blocks of code or nested namespaces — even if namespace were introduced after). The desirability of its interactions with overloading rules (the overloaded set doesn't contain the function defined in the base classes, nor in the enclosing blocks — now harmless as declaring functions in block is old fashioned —, nor in enclosing namespaces where the problem occasionally strikes as well) has been debated, to the point that G++ implemented alternative rules allowing the overloading, and B.S. argued that the current rule helps preventing errors in situations like (inspired from real live problems with g++)

    class X {
       int x;
    public:
       virtual void copy(X* p) { x = p->x; }
    };
    
    class XX: public X {
       int xx;
    public:
       virtual void copy(XX* p) { xx = p->xx; X::copy(p); }
    };
    
    void f(X a, XX b) 
    {
       a.copy(&b); // ok: copy X part of b
       b.copy(&a); // error: copy(X*) is hidden by copy(XX*)
    }
    

    Then B.S. continues

    In retrospect, I suspect that the overloading rules introduced in 2.0 might have been able to handle this case. Consider the call b.copy(&a). The variable b is an exact type match for the implicit argument of XX::copy, but requires a standard conversion to match X::copy. The variable a on the other hand, is an exact match for the explicit argument of X::copy, but requires a standard conversion to match XX:copy. Thus, had the overloading been allowed, the call would have been an error because it is ambiguous.

    But I fail to see where the ambiguity is. It seems to me that B.S. overlooked the fact that &a can't be implicitly converted to a XX* and thus only X::copy has be considered.

    Indeed trying with free (friends) functions

    void copy(X* t, X* p) { t->x = p->x; }
    void copy(XX* t, XX* p) { t-xx = p->xx; copy((X*)t, (X*)p); }
    

    I get no ambiguity error with current compilers and I don't see how rules in the Annotated C++ Reference Manual would makes a difference here.

提交回复
热议问题