16.6 AVOIDING NAME CONFLICTS FOR MEMBER FUNCTIONS


16.6 AVOIDING NAME CONFLICTS FOR MEMBER FUNCTIONS

Let's consider the hierarchy shown in Figure 16.11 in which we have a member function foo() defined originally for the common base X, and defined also for the derived classes Y, T, and U, with the implementation code as shown in the following program.

click to expand
Figure 16.11

 
//NameConflictMemFunc.cc #include <iostream> using namespace std; class X { public: void foo() { cout << "X's foo invoked" << endl; } }; class Y : virtual public X { public: void foo() { cout << "Y's foo invoked" << endl; } }; class T : virtual public X { public: void foo() {cout << "T's foo invoked" << endl;} //(A) }; class U : public Y, public T { public: void foo() {cout << "U's foo invoked" << endl;} //(B) }; int main() { U u; u.foo(); // U's foo invoked //(C) u.X::foo(); // X's foo invoked u.Y::foo(); // Y's foo invoked u.T::foo(); // T's foo invoked return 0; }

Even though U inherits two different version of foo() from the different inheritance paths, it does not cause any problems in the function call u.foo() in line (C) of main. That is because U has its own definition for foo() that hides all other inherited definitions of the same function name. But if we were to comment out U's definition of foo() in line (B), the statement in line (C) will give rise to a compilation error because of the name conflict between the two versions of foo() inherited by U.

What's interesting is that if we comment out both the U's definition for foo() and the definition in one of the two inheritance paths converging at U, the program will again work fine. That is, suppose we also comment out the definition of foo() in T in line (A), in addition to commenting out the definition in line (B), there will no problem with the compilation or the running of the program even though there is still a name conflict between the definition of foo() as inherited from Y and the definition of foo() as inherited from X through T. In this case, U will use the "most recent" definition of foo(), the one in Y in this case.

So we can always be sure that as long as a class where two or more inheritance paths converge has its own definition for member functions of the same signature that it inherits from the different paths, there is no name conflict problem. When such a class does not provide its own definition, then there can potentially be a name conflict. This name conflict will only be discovered if the member function in question is invoked on an object of that class or on objects of its derived classes. Therefore, name conflict problems for member functions can remain potentially hidden and may surface only at a later time when you or someone else tries to invoke those functions. To ward off such difficulties, it is best to be aware of such functions and to provide them with definitions in classes where inheritance paths converge.

The main of the program presented above also demonstrates that we can always access a superclass member function that is hidden in a derived class—even if the derived class is at the junction of converging inheritance paths—by invoking the scope operator on the superclass containing the desired function definition.




Programming With Objects[c] A Comparative Presentation of Object-Oriented Programming With C++ and Java
Programming with Objects: A Comparative Presentation of Object Oriented Programming with C++ and Java
ISBN: 0471268526
EAN: 2147483647
Year: 2005
Pages: 273
Authors: Avinash Kak

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net