简体   繁体   中英

C++: Ambiguos function call even with unique function names at each inheritence level

Code -

#include<iostream>
              
    using namespace std;
         
class P {
    public:
    void print()  { cout <<" Inside P"; }
    };
          
class Q : public P {
    public:
    void print() { cout <<" Inside Q"; }
    };
         
class Q2: public P {
    public:
    void print2() { cout <<" Inside Q2"; }
    };
          
class R: public Q2, public Q { };
          
int main(void)
{
    R r; 
    r.print(); // error: request for member ‘print’ is ambiguous
    return 0;
}

Expected behavior: No ambiguous call on 3rd line in main.

Actual behavior: Ambiguous call on 3rd line in main

Rationale: I expected class Q to hide the print() function of class P. I would expect an ambiguous call error when Q2 has the same function name as R or Q (or even P?). But I deliberately changed the function name in Q2 to 'print2' to avoid this error. This error goes away when I remove 'Q2' as parent class of R. Is this happening because 'Q2' inherits 'print' from 'P'?

Note: I know similar questions have been asked on data hiding for regular inheritance and ambiguous calls in case of inheritance from multiple classes, but this case is sort of a mixture of two, and I did not find any specific answers.

I expected class Q to hide the print() function of class P

This has nothing to do with Q hiding the superclass's print() .

Q2 inherits from P , and therefore inherits print() .

class R: public Q2, public Q { };

print() is inherited from both Q2 and from Q. Whether they turn out to be the same or different methods is immaterial. The point is that it is ambigous which print() method R.print() resolves to.

would expect an ambiguous call error when Q2 has the same function name

But it does. It inherits it.

This is very typical C++ Diamond problem with multiple inheritance.

what you have is when R call the print functions he does not know from which print to cal.

you can solve this by helping the R class object to specify which print you want to call.

below modification can illustrate this.

#include<iostream>
              
    using namespace std;
         
class P {
    public:
    void print()  { cout <<" Inside P\n"; }
    };
          
class Q : public P {
    public:
    void print() { cout <<" Inside Q\n"; }
    };
         
class Q2: public P {
    public:
    void print2() { cout <<" Inside Q2\n"; }
    };
          
class R: public Q2, public Q { };
          
int main(void)
{
    R r; 
    r.Q::print(); 
    r.Q2::print();
    // r.P::print();  ambiguous base call.
    // r.print();     ambiguous member
    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM