I have classes with inherits from other classes. I am looking for pattern which will allow me to break this type of class to class inheritance and use Interface instead.
For example:
Consider I have Base class and few derive classes as follows
Lib A :
class Base { ... }
Clients:
class Derived1 : public Base { ... }
class Derived2 : public Base { ... }
class Derived3 : public Derived2 { ... }
And clients uses objects of Base, Derived1, Derived2, Derived3.
I want to keep expose Base as interface.
Such that,
Lib A will contain:
Interface IBase ( exposed )
and Class BaseImpl ( internal )
And clients will use
class Derived1 : public IBase { .. }
class Derived2 : public IBase { .. }
class Derived3 : public IBase { .. }
Now problem is, if I make changes as above, I will loose default implementation provided by BaseImpl here.
1 possible solution that I could think of is having factory as:
Lib A:
Interface IBase { ... }
class BaseImpl : public IBase {
...
}
export static IBase* GetDefaultBase()
{
return new Base();
}
clients:
class Derived1 : public IBase
{
public:
Derived1() {
m_base = GetDefaultBase();
}
// and all implemented apis can use m_base to call default behavior provided by BaseImpl.
I dont see any issues with this approach. But I am curious to know, are there any well known pattern / solutions available for such refactoring problem?
Thanks,
Kailas
Related
I have the following interfaces and classes
public interface IBase
{
virtual void SomeBaseMethod()=0;
}
public interface IDerived : IBase
{
virtual void SomeOtherMethod()=0;
}
public class base: public IBase
{
void SomeBaseMethod(){};
}
public class derived: public base, public IDerived
{
void SomeBaseMethod(){};
void SomeOtherMethod(){};
}
In class derived, I have to repeat 'void SomeBaseMethod(){};', which have already implement in my class base. Otherwise I will get compile error. Is it possible not repeat 'void SomeBaseMethod(){};' in my class derived?
Unfortunately, you have to repeat yourself here. C++ has virtual inheritance, which would solve this problem, but you can't use virtual inheritance with COM interfaces. Here's an explanation as to why.
Consider this example of code:
class Base
{
public:
Base() {}
};
class Derived1 : public Base
{
public:
Derived1() : Base() {}
};
class Derived2 : public Base
{
public:
Derived2() : Base() {}
};
Is there any to make that Derived1 has-a Derived2 and Derived2 has-a Derived1?
The best solution would be by using a third class which has those two objects. But in case high performance is needed?
An example might be a two-way client-server application.
EDIT: Consider that that's just a summary example. In the real code each of the three classes could throw an exception; I made sure that the code is exception-safe, though.
You can accomplish a "has-a" relationship with a forward declaration which basically tells "this class exists, it's just not declared yet"
#include <iostream>
using namespace std;
class Base
{
public:
Base() {}
};
// Forward declaration
class Derived1;
class Derived2 : public Base
{
friend class Derived1;
public:
Derived2() : Base() {}
private:
Derived1 *ptr;
};
class Derived1 : public Base
{
public:
Derived1(Derived2& obj) : Base(), ptr(&obj) {
obj.ptr = this;
}
private:
Derived2 *ptr;
};
int main() {
Derived2 obj2;
Derived1 obj1(obj2);
return 0;
}
http://ideone.com/RVU8AR
This way the two classes can communicate with each other. Notice the private pointers and the initialization into the constructor. With the "friend" declaration one class is able to modify the other class's private members.
Each class can hold a pointer:?
class Derived1
Derived2 *p_d2;
class Derived2
Derived1 *p_d1;
I have a quite special situation in my C++ program.
Look at the following class setup:
class Base1 {
public: void baseMethod();
}
class Base2 : public Base1 {
...
}
class Common {
public: void commonMethod();
}
class Derived1 : public Base1, public Common {
...
}
class Derived2 : public Base2, public Common {
...
}
Base1 and Base2 are unchangeable for me as they are part of a library.
What I want to achieve is that both Derived1 and Derived2 share the same method commonMethod(), so I use class Common with that method as a common base for Derived1 and Derived2.
The problem now is that commonMethod() shall contain a call to baseMethod() which is defined in Base1! In the context of a Derived1- or Derived2-object this is legal, but how to define that method in Common?
I know that if I would declare Base2 as virtual derived class from Base1 and the same for Common, it shouldn't be a problem (at least for Derived2, not sure about Derived1). But as I can't modify Base2 that's not possible anyway.
Also letting Common inherit from Base2 and then Derived1 and Derived2 solely from Common doesn't work because I don't want Derived1 to inherit from Base2!
What then came to my mind was to make a dynamic_cast within commonMethod():
void Common::commonMethod() {
...
Base1* self = dynamic_cast<Base1*>(this);
if(self) {
self->baseMethod();
}
...
}
This seems to work, but I'm not sure if this is a "nice" solution...
Do you have any ideas how to make it better? Or do you think this solution isn't bad at all? :)
If the only purpose of Common is to provide a common implementation of that one method, you can use the CRTP pattern and template it on the type of the base. At this point you could decide whether it makes sense to keep it as multiple bases of the DerivedX types or it could make sense to linearize the inheritance hierarchy:
// Option1
template <typename Derived>
struct Common {
void commonFunction() { ... static_cast<Derived*>(this)->foo(); ... }
};
struct Derived1 : Base1, Common<Derived1>
// Option2 (not strictly CRTP, but close)
template <typename Base>
struct Common : Base {
void commonFunction() { ... this->foo(); ... } // keep the this-> here
};
struct Derived1 : Common<Base1>
If I were you, I'd choose composition over multiple inheritance, i.e. to define common as a member object of derived classes.
class Base1 {
public: void baseMethod();
}
class Base2 : public Base1 {}
class Common {
public:
Common(Base1 *base): m_base(base) {}
void Common::commonMethod()
{
m_base->baseMethod();
}
private:
Base1 *m_base;
}
class Derived1 : public Base1
{
public:
Derived2(): m_common(this) {}
private:
Common m_common;
}
class Derived2 : public Base2
{
public:
Derived2(): m_common(this) {}
private:
Common m_common;
}
There is a potential risk of going this way though. Since member object(Common) is constructed first before the outer object(Derived1 or Derived2), you want to make sure no methods from the Derivedx object is called in Common's constructor.
Lets suppose you want to make an interface of the class Derived and it looks like this:
class Derived : public Base
{
public:
foo();
}
class Base
{
public:
tii();
//many other methods
}
How would you do the Interface? How can you make Base::tii visible (and also other methods) to this new interface?
class IDerived
{
public:
virtual foo() = 0;
// should I declare here tii() as a pure virtual function?
// but by doing it now there is ambiguity!
}
What is a good strategy?
The new Derived class should look like this....
class Derived : public Base, public IDerived
{
//implement the real thing
}
Your example is doing things backwards: the interface should be defined independently of any concrete classes with all pure virtual methods:
class IDerived
{
public:
virtual void foo() = 0;
virtual ~IDerived() {} // don't forget to include a virtual destructor
}
And the concrete classes will derive publicly from the interface:
class Derived : public Base, public IDerived
{
public:
void foo();
}
If you want IDerived to also declare methods that Derived inherits from Base, you can have Derived explicitly implement the method by calling the inherited implementation:
class Derived : public Base, public IDerived
{
public:
void foo();
void bar() { Base::bar(); }
}
At front, I dislike interfaces (they are grown by other languages than c++).
Anyway, if you have one, it should be complete: Hence have the 'tii() as a pure virtual function'. To resolve the conflict rewrite that function in 'Derived' (forward to Base::tii).
I've got the following class structure:
class Common {
//members and data here.
};
class Derived1 : public Common
{
};
class Derived2: public Common, public Derived1
{
};
As I understand this hierarchy both Derived1 and Derived2 will share any members from Common.
Is there a way with out making Derived1 private in Derived2 to allow Derived2 to still inherit from Common but have separate function overrides.
Basically i need to override a virtual function in Derived1, and Derived2 but still have Derived1's function run (it's a threading api).
Any help apreciated.
As #Walkerneo points out, you don't need to inherit from both Common and Derived1. You can simply inherit from Derived1 and you'll also get inheritance from Common. You can explicitly call Derived1's method from Derived2's method by doing the following:
void Derived2::overriddenMethod ()
{
// Do something unique here
Derived1::overriddenMethod ();
// Maybe do some more stuff
}
You can achieve this even with single inheritance:
struct Base
{
virtual void foo() = 0;
virtual ~Base() { }
};
struct Intermediate : Base
{
virtual void foo() { /* ... */ }
// ...
};
struct Derived : Intermediate
{
virtual void foo()
{
Intermediate::foo();
// new stuff
}
};
Have you tried using virtual functions for runtime polymorphism and assigning a variable of your Derived2 class to a pointer of Derived1 class
class Common {
//members and data here.
public:
virtual void commonFunction() = 0; //keeping it pure virtual
};
class Derived1 : public Common
{
virtual void commonFunction(){
//do something in derived1
}
};
class Derived2: public Common, public Derived1
{
void commonFunction(){
//do something in derived2
}
};
int main(){
Derived2 derived2;
Derived1 *derived1;
derived1 = &derived2;
derived1->commonFunction(); //calls the common function definition in Derived1
/* ... */
}