Linking issue

I have a linking issue due to lack of implemented pure virtual methods. I know multiple inheritance is frowned upon but I am hoping to solve this issue without rewriting an entirely new class. I have placed stubs in the Derived class below to force the desired call to happen but every time I use these two classes in conjunction, I have to put these stubs. Is there any way to do this automagically? Sorry if this is a simple issue, I cannot figure out an effective search to find the answer.
Thanks

Class InterfaceClass
{
virtual void method1() = 0;
virtual void method2() = 0;
}

Class BaseClass
{
void method1()
{
}
void method2()
{
}
}

Class DerivedClass :
public InterfaceClass,
public BaseClass
{
// How can I remove these "stubs" so that the B::method1 and B::method2 automatically
// detected?
void method1() { BaseClass::method1() }
void method2() { BaseClass::method2() }
}
[1035 byte] By [ArtVandelay] at [2007-11-19 18:29:59]
# 1 Re: Linking issue
class InterfaceClass
{
virtual void method1() = 0;
virtual void method2() = 0;
};

class BaseClass : public InterfaceClass
{
void method1(){}
void method2(){}
};

class DerivedClass : public BaseClass
{
};

not sure why you are doing this, seems like a design flaw to me.
souldog at 2007-11-9 0:55:52 >
# 2 Re: Linking issue
Souldog,
Thanks for your response. First of all, I left a lot of details out of my example to make the question easier. The following is a better representation... Because the Base Class can only define two of the four pure virtual methods (due to the base class needing to service many different interfaces). I hope this makes my question more clear...

Class InterfaceClass1
{
virtual void method1() = 0;
virtual void method2() = 0;
virtual void method3a() = 0;
virtual void method4a() = 0;
}

Class InterfaceClass2
{
virtual void method1() = 0;
virtual void method2() = 0;
virtual void method3b() = 0;
virtual void method4b() = 0;
}

Class BaseClass
{
void method1()
{
}
void method2()
{
}
}

Class DerivedClass1 :
public InterfaceClass1,
public BaseClass
{
// How can I remove these "stubs" so that the B::method1 and B::method2 automatically
// detected?
void method1() { BaseClass::method1() }
void method2() { BaseClass::method2() }
void method3a() { BaseClass::method3a() }
void method4a() { BaseClass::method4a() }
}

Class DerivedClass2 :
public InterfaceClass2,
public BaseClass
{
// How can I remove these "stubs" so that the B::method1 and B::method2 automatically
// detected?
void method1() { BaseClass::method1() }
void method2() { BaseClass::method2() }
void method3b() { BaseClass::method3b() }
void method4b() { BaseClass::method4b() }
}
ArtVandelay at 2007-11-9 0:56:46 >
# 3 Re: Linking issue
So you have a bunch of interface classes all of which have method1 and method2.

You have decided that you do not want to implement these functions but have
a problem because they are pure virtual. (design flaw)

You are trying to find a way to provide a bass class that "implements" these functions so you don't have to think about them when coding derived classes.

Is this correct?

PS:
what is going on here
void method3a() { BaseClass::method3a() }
void method4a() { BaseClass::method4a() }
void method3b() { BaseClass::method3b() }
void method4b() { BaseClass::method4b() }
souldog at 2007-11-9 0:57:47 >
# 4 Re: Linking issue
"You have decided that you do not want to implement these functions but have
a problem because they are pure virtual. (design flaw)"
Response: These pure virtual methods are added to each interface by a code generator from a Corba IDL file. The output cannot be fenagled to match my design since this would increase the amount of work a great deal each time the generated files were recreated...

"You are trying to find a way to provide a bass class that "implements" these functions so you don't have to think about them when coding derived classes. Is this correct?"
Response: It is not so much that I do not have to think about them but rather that each method performs the same aciton. The reason I do not put the implementation in the Interface classes themselves is also because, as listed above, these files are generated by from an IDL and I feel it would be counterproductive to have to change each interface by hand after it is generated.

"PS:
what is going on here
void method3a() { BaseClass::method3a() }
void method4a() { BaseClass::method4a() }
void method3b() { BaseClass::method3b() }
void method4b() { BaseClass::method4b() }"
Response: What I am doing here is providing an explicit call to the BaseClass implementation of the methods I would like to make common with the base class (I incorrectly added base class calls for methods 1 and 2 when methods 1 and 2 are supposed to be unique in each InterfaceClass1 and InterfaceClass2. The "stubs", as I have been calling them, are necessary because the linking phase fails without this because the implementation of these methods in the base class are not seen by the linker. This is eactly what I am trying to prevent.
ArtVandelay at 2007-11-9 0:58:51 >
# 5 Re: Linking issue
I figured it had to do with code that you could not easily change

class InterfaceClass1
{
virtual void method1() = 0;
virtual void method2() = 0;
virtual void method3a() = 0;
virtual void method4a() = 0;
};

class InterfaceClass2
{
virtual void method1() = 0;
virtual void method2() = 0;
virtual void method3b() = 0;
virtual void method4b() = 0;
};

template<class K>
class BaseClass : public K
{
void method1(){}
void method2(){}
};

class DerivedClass1 : public BaseClass<InterfaceClass1>
{
virtual void method3a(){}
virtual void method4a(){}
};

class DerivedClass2 : public BaseClass<InterfaceClass2>
{
virtual void method3b(){}
virtual void method4b(){}
};

still don't understand
void method3a() { BaseClass::method3a() }
void method4a() { BaseClass::method4a() }
void method3b() { BaseClass::method3b() }
void method4b() { BaseClass::method4b() }
since BaseClass does not implement these methods.
I think maybe you are just mixing notation.
souldog at 2007-11-9 0:59:56 >
# 6 Re: Linking issue
Ok, let me re-write this and see if I can get it right this time...

I would like to have DerivedClass1 be of type InterfaceClass1 and use BaseClass to implement the common portion of the InterfaceClass1 definition as well as DerivedClass2 being of type InterfaceClass2 with BaseClass implementing the common portion InterfaceClass2. This is pretty much just to prevent DerivedClass1 and 2 from having to implement the same code since it is exactly the same for both derived classes but the other interface methods are unique. Did I explain it better this time? BTW, I am familiar with templates and I don't think that is appropriate since the BaseClass will only implement a portion of the InterfaceClass1 and 2 and there are portions of each of those interface classes that aren't common for the BaseClass to make virtual for the derived class. That approach I believe would force the BaseClass to implement methodA, B, C and D as virtual for the derived class to handle (in reality, many, many more since this is example is extremely scaled down)

class InterfaceClass1
{
virtual void methodA() = 0;
virtual void methodB() = 0;
virtual void commonMethod1() = 0;
virtual void commonMethod2() = 0;
};

class InterfaceClass2
{
virtual void methodC() = 0;
virtual void methodD() = 0;
virtual void commonMethod1() = 0;
virtual void commonMethod2() = 0;
};

class BaseClass
{
void commonMethod1(){}
void commonMethod2(){}
};

class DerivedClass1 :
public BaseClass,
public InterfaceClass1
{
//commonMethod1 and commonMethod2 are implemented by BaseClass
void methodA(){ ...do something... }
void methodB(){ ...do something... }
};

class DerivedClass2 :
public BaseClass,
public InterfaceClass2
{
//commonMethod1 and commonMethod2 are implemented by BaseClass
void methodC(){ ...do something... }
void methodD(){ ...do something... }
};
ArtVandelay at 2007-11-9 1:00:50 >
# 7 Re: Linking issue
I understand what you are trying to do now. I apologize that you had stated your question in a confusing manner. Using multiple inheritance is not
going to solve your problem since the vtables for the interface classes and BaseClass
are not related.

Templates will solve your problem and you will not have to implement A, B, C and D
in BaseClass. Why don't you try it.

I did and it compiled fine, at least with VC++ 6.0 (which is not very complient with the
standard)
souldog at 2007-11-9 1:01:57 >
# 8 Re: Linking issue
Will do. Thanks for your help. I am sorry for the confusion.

Much appreciated!
ArtVandelay at 2007-11-9 1:02:58 >
# 9 Re: Linking issue
remember that a template class is "ignored" until it is used. At the point when it is used
here, overides for all pure virtual functions are provided, either by BaseClass or by the derived class.
souldog at 2007-11-9 1:03:54 >
# 10 Re: Linking issue
Let me know if it works for you. I am curious
souldog at 2007-11-9 1:05:04 >
# 11 Re: Linking issue
The design as OP suggests in flawed, not because of the interfaces but because of non-virtual functions in the BaseClass and repeatition of names. They have the same name as the pure virtual functions in the interfaces. This will create a lot of confusions (visible this time as well as in future). The functions in BaseClass are non-virtual.. their names should not appear in a derived class (and it appears in both the interface as well as the derived classes). What this does is - hides all the base versions of the functions (base versions to the names appearing in the derived one) - the versions in BaseClass.

Hence you "have" to use what you are calling a stub.. you will "have" to qualify the functions name as BaseClass::method1() etc.

Run this code and you shall see that it results in a stack overflow.. because it is not able to see the implementation of method1 as in BaseClass and hence ends up in a infinite recursive call to itself.
#include<iostream>
class InterfaceClass1{
public:
virtual void method1() = 0;
virtual void method2() = 0;
virtual void method3a() = 0;
virtual void method4a() = 0;
};

class InterfaceClass2{
public:
virtual void method1() = 0;
virtual void method2() = 0;
virtual void method3b() = 0;
virtual void method4b() = 0;
};

class BaseClass{
public:
void method1(){std::cout << "Baseclass method1() called\n"; }
void method2(){std::cout << "Baseclass method2() called\n"; }
};

class DerivedClass1 : public InterfaceClass1, public BaseClass {
// How can I remove these "stubs" so that the B::method1 and B::method2 automatically
// detected?
public:
void method1() { method1(); }
void method2() { method2(); }
void method3a() { std::cout << "method3a() called\n"; }
void method4a() { std::cout << "method4a() called\n"; }
};

class DerivedClass2 : public InterfaceClass2, public BaseClass {
// How can I remove these "stubs" so that the B::method1 and B::method2 automatically
// detected?
public:
void method1() { BaseClass::method1(); }
void method2() { BaseClass::method2(); }
void method3b() { std::cout << "method3b() called\n"; }
void method4b() { std::cout << "method4b() called\n"; }
};

int main(){
DerivedClass1 obj;
obj.method1();
obj.method2();
obj.method3a();
obj.method4a();
InterfaceClass1& ref = obj;
ref.method1();
ref.method2();
ref.method3a();
ref.method4a();
return 0;
}To fix this issue - you need to keep the calls well qualified by their full names.
class DerivedClass1 : public InterfaceClass1, public BaseClass {
// How can I remove these "stubs" so that the B::method1 and B::method2 automatically
// detected?
public:
void method1() { BaseClass::method1(); }
void method2() { BaseClass::method2(); }
void method3a() { std::cout << "method3a() called\n"; }
void method4a() { std::cout << "method4a() called\n"; }
};However, there is no simple solution to this when you are inheriting from multiple classes (and more than one of those bases has a repeating name for a function). You will have to qualify the full name even if those BaseClass versions have been made virtual functions. Also, I must say the need seems pretty wierd to me.. what is your problem? What do you want to do? Can you write a small program stating what you want and what you are doing ... how you want to achieve that.. Make the program such that it is compilable. Regards.
exterminator at 2007-11-9 1:05:57 >
# 12 Re: Linking issue
Here's another way of achieving a similar result
Class InterfaceClass
{
public:
virtual void method1() {}
virtual void method2() {}
protected:
InterfaceClass() {}
};

Class DerivedClass :
public InterfaceClass
{
};
googler at 2007-11-9 1:06:57 >
# 13 Re: Linking issue
As the op has stated, he is trying to overcome a limitation in an automatic code generator.
The condition, googler, is that the interface classes can not be modified. If they could
then the obvious thing to do is to change them to meet the ops design goals.

Exterminator, it is true that multiple inheritance is not the way to go here and
your explanation is apt.

It seems to me that the only good solution is to inject a class into the heirarchy between
the interface classes and the derived classes that has the default methods implemented, but does not need to implement the rest of the virtual methods.

Did you guys try the template method.
souldog at 2007-11-9 1:08:04 >
# 14 Re: Linking issue
As the op has stated, he is trying to overcome a limitation in an automatic code generator.
I missed that part. How about this then
Class InterfaceClass
{
public:
virtual void method1() = 0;
virtual void method2() = 0;
};

Class BaseClass : public InterfaceClass
{
public:
void method1()
{
}
void method2()
{
}
protected:
BaseClass() {}
};

Class DerivedClass : public BaseClass
{
};

It seems to me that the only good solution is to inject a class into the heirarchy between the interface classes and the derived classes that has the default methods implemented, but does not need to implement the rest of the virtual methods.
Right, like above.
googler at 2007-11-9 1:09:04 >
# 15 Re: Linking issue
googler, I think maybe you should actually read the thread.
The ops problem has already been solved
souldog at 2007-11-9 1:10:00 >
# 16 Re: Linking issue
So did you guys read the thread?
Aaah... I am really sorry, souldog... I missed a few of them.. the one that was the most important to understand what he wanted when he said that he wanted BaseClass to implement the common members of both the interfaces...It seems to me that the only good solution is to inject a class into the heirarchy between
the interface classes and the derived classes that has the default methods implemented, but does not need to implement the rest of the virtual methods.

Did you guys try the template method.Yup.. I tried... it works.. A very nice solution indeed souldog... :thumb: (I wish I had read that post OP :blush: instead of getting embarrassed now).

I don't think there is a problem with implementing a bunch of functions in another interface and then making the concrete class deriving from it and needing only to provide the implementation for the rest of the abstract functions not over-ridden in the intermediate class (BaseClass here).

I got tempted to keep away of the template way and providing a BaseClass that derived from both interfaces but in that case ... since Derived1 and Derived2 have some un-common interface members (3a, 3b, 4a, 4b).. it made them inherit them as well and hence since they did not know about how to implement those functions.. they(derived1 and derived2) themselves became abstracts.. which is not right! They are seperate except for the common part put in BaseClass. I wasted some of my time trying that out... but it only helped consolidate the correctness of your method.. :thumb: Best regards.
exterminator at 2007-11-9 1:11:09 >
# 17 Re: Linking issue
googler, I think maybe you should actually read the thread. The ops problem has already been solved
Right. I guess I should follow my own ( http://www.dev-archive.com/forum/showpost.php?p=1324577&postcount=21) advice, but there were just so many words to read. :wave:
googler at 2007-11-9 1:12:09 >
# 18 Re: Linking issue
no problem guys. I only harped on this because I was curious if there was some
problem with the template method that I am not aware of, and so wanted some
other people to look at it.
souldog at 2007-11-9 1:13:03 >
# 19 Re: Linking issue
I was curious if there was some problem with the template method that I am not aware of...
I'd give the templates a protected default constructor to protect them from unintended use (make them pseudo-abstract), but that's not a problem per se, just a design quirk.
googler at 2007-11-9 1:14:10 >
# 20 Re: Linking issue
Souldog,
You were correct. The template did work. I had already implemented the BaseClass as a template but I was using the derived class to inherit from the InterfaceClass and then using the DerivedClass as the type for the template. I don't know how I came up with that but all I did was change the DerivedClass to inherit from the BaseClass and pass the InterfaceClass into the BaseClass as the template type.

Your help is very much appreciated as well as everyone else who chipped in with their ideas.
Thanks!
Art
ArtVandelay at 2007-11-9 1:15:07 >