Refactoring a leaf class to a base class, and keeping it also a interface implementation

Posted by elcuco on Stack Overflow See other posts from Stack Overflow or by elcuco
Published on 2010-06-15T09:29:22Z Indexed on 2010/06/15 9:32 UTC
Read the original article Hit count: 267

I am trying to refactor a working code. The code basically derives an interface class into a working implementation, and I want to use this implementation outside the original project as a standalone class.

However, I do not want to create a fork, and I want the original project to be able to take out their implementation, and use mine. The problem is that the hierarchy structure is very different and I am not sure if this would work. I also cannot use the original base class in my project, since in reality it's quite entangled in the project (too many classes, includes) and I need to take care of only a subdomain of the problems the original project is.

I wrote this code to test an idea how to implement this, and while it's working, I am not sure I like it:

#include <iostream>

// Original code is:
// IBase -> Derived1

// I need to refactor Derive2 to be both indipendet class
// and programmers should also be able to use the interface class
// Derived2 -> MyClass + IBase
// MyClass


class IBase {
public:
    virtual void printMsg() = 0;
};

///////////////////////////////////////////////////
class Derived1 : public IBase {
public:
    virtual void printMsg(){ std::cout << "Hello from Derived 1" << std::endl; }
};


//////////////////////////////////////////////////
class MyClass {
public:
    virtual void printMsg(){ std::cout << "Hello from MyClass" << std::endl; }
};

class Derived2: public IBase, public MyClass{
    virtual void printMsg(){ MyClass::printMsg(); }
};

class Derived3: public MyClass, public IBase{
    virtual void printMsg(){ MyClass::printMsg(); }
};

int main()
{
    IBase *o1 = new Derived1();
    IBase *o2 = new Derived2();
    IBase *o3 = new Derived3();
    MyClass *o4 = new MyClass();

    o1->printMsg();
    o2->printMsg();
    o3->printMsg();
    o4->printMsg();

    return 0;
}

The output is working as expected (tested using gcc and clang, 2 different C++ implementations so I think I am safe here):

[elcuco@pinky ~/src/googlecode/qtedit4/tools/qtsourceview/qate/tests] ./test1
Hello from Derived 1
Hello from MyClass
Hello from MyClass
Hello from MyClass
[elcuco@pinky ~/src/googlecode/qtedit4/tools/qtsourceview/qate/tests] ./test1.clang 
Hello from Derived 1
Hello from MyClass
Hello from MyClass
Hello from MyClass



The question is

My original code was:

class Derived3: public MyClass, public IBase{
    virtual void IBase::printMsg(){ MyClass::printMsg(); }
};

Which is what I want to express, but this does not compile. I must admit I do not fully understand why this code work, as I expect that the new method Derived3::printMsg() will be an implementation of MyClass::printMsg() and not IBase::printMsg() (even tough this is what I do want).

How does the compiler chooses which method to re-implement, when two "sister classes" have the same virtual function name?

If anyone has a better way of implementing this, I would like to know as well :)

© Stack Overflow or respective owner

Related posts about c++

Related posts about interface