Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overriding Qualified Virtual Methods

I have C++ class with multiple parents; each parent defines a function with a common name but a different purpose:

class BaseA
{
    virtual void myFunc();  // does some task
};
class BaseB
{
    virtual void myFunc();  // does some other task
};
class Derived : public BaseA, public BaseB;

If that was it, I would have no problem - I could resolve the ambiguity it with a using statement, and I could choose which one to call using the base class names and the scope resolution operator.

Unfortunately, the derived class needs to override them both:

class Derived : public BaseA, public BaseB
{
    virtual void BaseA::myFunc(); // Derived needs to change the way both tasks are done
    virtual void BaseB::myFunc();
}

This doesn't work, not because it introduces a new ambiguity (although it may), but because

"error C3240: 'myFunc' : must be a non-overloaded abstract member function of 'BaseA'"

"error C2838: illegal qualified name in member declaration"

Under different circumstances I might just rename the methods, or make them pure virtual as the compiler suggests. However, the class hierarchy structure and a number of external issues make the first option extremely difficult, and the second impossible.

Does anyone have a suggestion? Why are qualifiers only allowed for pure virtual methods? Is there any way to simultaneously override virtual methods and resolve ambiguities?

like image 487
John Avatar asked Mar 30 '11 02:03

John


1 Answers

Microsoft allows that syntax (it's available beginning in Visual C++ 2005). They also introduced a new, more powerful syntax for managed code only.

Neither one was included in C++0x.

See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2108.html


I think this is a workaround:

class BaseA
{
protected:
    virtual void myFunc();  // does some task
};
class BaseB
{
protected:
    virtual void myFunc();  // does some other task
};
class ShimA : virtual BaseA
{
    virtual void myFunc() { myFuncA(); }
protected:
    virtual void myFuncA() { BaseA::myFunc(); }
};
class ShimB : virtual BaseB
{
    virtual void myFunc() { myFuncB(); }
protected:
    virtual void myFuncB() { BaseB::myFunc(); }
};
class Derived : public virtual BaseA, public virtual BaseB, protected ShimA, protected ShimB
{
     virtual void myFuncA() {}
     virtual void myFuncB() {}
};
like image 138
Ben Voigt Avatar answered Sep 22 '22 01:09

Ben Voigt