Hi all. I have a scenario where i have two interfaces, IA and IB. IB is an extension of IA. I also have two implementations of the said interfaces, AImpl and BImpl. I let BImpl inherit from AImpl in order to take care of the IA implementation part of IB. I have used this technique before in Java, but in C++ (VS and GCC), it seems like the IB methods inherited from IA needs to be re-implemented in BImpl, inheriting from AImpl does not help. Below is an example of what I mean: -
#include <cstdio>
-
-
class IA { public: virtual void m1() = 0; };
-
class IB: public IA { public: virtual void m2() = 0; };
-
-
class AImpl: public IA {public: void m1() { printf("m1"); }};
-
class BImpl: public IB, public AImpl {public: void m2() { printf("m2"); }};
-
-
int main() { BImpl b; b.m2(); return 0; }
-
This does not compile, since the compilers say that IB::m1 is not implemented
in BImpl. What I would like is for BImpl to inherit the implementation of m1 from AImpl, thus making BImpl indirectly implement IB::m1 (an thus all IB). This does not seem to work. What can I do to make this work?
Thank you in advance
8 1885
That won't work in Java either. To inherit functionality you need to inherit from classes not from interfaces. i.e your BImpl must inherit from AImpl for you to get the functionality in AImpl to be available in BImpl.
your BImpl must inherit from AImpl for you to get the functionality in AImpl to be available in BImpl
But it does:
class BImpl: public IB, public AImpl
Or did I misinterpret multiple inheritance?
What happens when you make those functions 'virtual' in your implementation?
kind regards,
Jos
What happens when you make those functions 'virtual' in your implementation?
That doesn't help. Virtual is inherited and cannot be undone if I remember correctly. I found the answer however. I am sorry to have wasted you time, but it is always when you decide to post a question that you figure it out :)
My example is an example of the "dreaded diamond", see http://www.parashift.com/c++-faq-lit...heritance.html, Where IB and AImpl are the middle-level classes.
In order to solve my problem, I had to use virtual inheritance for IB and AImpl. So (once again in c++), it seems like I need to modify the interface in order to implement it properly :)
The working solution is: - #include <cstdio>
-
-
class IA { public: virtual void m1() = 0; };
-
class IB: public virtual IA { public: virtual void m2() = 0; };
-
-
class AImpl: public virtual IA { public: virtual void m1() { printf("m1"); } };
-
class BImpl: public IB, public AImpl { public: void m2() { printf("m2"); } };
-
-
int main() {
-
AImpl a;
-
a.m1();
-
BImpl b;
-
b.m1();
-
b.m2();
-
return 0;
-
}
Maybe there is another way of accomplishing this that doesn't require modifying the IB interface, or maybe there is a guideline that says "always use virtual inheritance when modelling interfaces" or something? Any tips or pointers welcome, still trying to learn...
Oh, and the extra "virtual" in AImpl::m1 can be removed, I used that to try JosAH's idea.
#include <cstdio>
class IA { public: virtual void m1() = 0; };
class IB: public IA { public: virtual void m2() = 0; };
class AImpl: public IA {public: void m1() { printf("m1"); }};
class BImpl: public IB, public AImpl {public: void m2() { printf("m2"); }};
int main() { BImpl b; b.m2(); return 0; }
BImpl inherits from IB which inherits from IA which an abstract base class because IA::m1 is a pure virtual function. This function is not implemented anywhere in IB so BImpl is also an abstract base class and you die in compilation tryin to create an instance of an abstract class.
Then if you implement m1() in IB you have two m1()'s so in main() b.m1() won't work forcing you to code b.IB::m1().
I'm trying to use this methodology to hide the implementation of a DLL library from the client. I came from Linux, trying to learn Win for my new work (a bit backwards, I know :) ).
After doing some research, I've found an equivalent discussion here:
http://www.archivum.info/comp.lang.c++/2008-08/msg00431.html
It basically suggests to use virtual inheritance when implementing (or extending) interfaces, and that you can ignore the VS warnings you get when you do this. GCC just compiles cleanly without warnings.
I you are interested in binary encapsulation related to interfaces and C++, another really good read on the topic (surprisingly) turned out to be the first chapter of "Essential COM" by Don Box, you can google "COM as a better C++". This chapter explains that this problem (implementation hiding with interfaces) was basically the rationale behind the decision to invent COM (a windows reusable components framework). COM now seems to have grown plenty of its own complexities, but the good ideas behind it are well explained in that book.
Thanks everyone for your help.
You hide an implementation by using an interface class or a set of interface functions.
You do not hide an implentation by using public virtual functions. All virtual functions should be private. The reason for this is that the public members of a base class is the hierarchy interface. Overidding one of those functions, omits that part of the interface in the derived class. Worse, the public virtual function exposes how you implement the feature in your derived class. Worse, it forces all derived classes to support the same functions, even if they don't apply.
Check out the Template design pattern.
Research separating the interface from the implementation. In this respect Don Box and COM in general is outdated. I know, I know, you see public virtual functions every day. But that is just the argument that if you repeat something often enough, it becomes true.
All you provide the use of the DLL is a header file. None of your classes should be exposed. Then if you use the extern "C" feature with your interface functions, you can compile your DLL in C++, using any C++ features or STL goodies, and still make calls into the DLL using a program compiled in C.
Sign in to post your reply or Sign up for a free account.
Similar topics
by: Slavyan |
last post by:
(I just started to learn C#.NET)
What's the syntax in c# for a class to inherit more than one class.
I know following syntax:
public class MyClass : MyOtherClass
{
}
but I need to inherit...
|
by: Lauro |
last post by:
I'm starting whit C++, so I don't andestand too much about .
I would like to know how can I inherit a generic class fron
CObjet class, all the time I try I recibe a message telling that
CObjet...
|
by: Charlie |
last post by:
Hi:
The code to add items to shopping cart is a seperate class file so I don't
have to keep repeating it. If I want to be able to access session data in
this class, which class should I base it...
|
by: Mark Fink |
last post by:
I wrote a Jython class that inherits from a Java class and (thats the
plan) overrides one method. Everything should stay the same.
If I run this nothing happens whereas if I run the Java class it...
|
by: T.A. |
last post by:
I understand why it is not safe to inherit from STL containers, but I have
found (in SGI STL documentation) that for example bidirectional_iterator
class can be used to create your own iterator...
|
by: K Viltersten |
last post by:
Suppose there is the following class structure.
class S {...}
class A : S {...}
class B : S {...}
class A1 : A {void m(){...}}
class B1 : B {void m(){...}}
class B2 : B {...}
Just to clarify...
|
by: epanda |
last post by:
Hi,
I would like to merge two class which have got 90% of same source
code. But I don't know what to do.
class A {
int putLightOn () {
switch(status)
|
by: Chris |
last post by:
Hi,
I'm kind of new to the more involved workings of javascript, and am
having a few problems.
My problem is this: I am working with a CMS which is including various
javascrip files in the...
|
by: GTalbot |
last post by:
Hello fellow comp.infosystems.www.authoring.stylesheets colleagues,
Imagine this situation:
#grand-parent-abs-pos
{
height: 400px;
position: absolute;
width: 600px;
}
|
by: Charles Arthur |
last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
|
by: aa123db |
last post by:
Variable and constants
Use var or let for variables and const fror constants.
Var foo ='bar';
Let foo ='bar';const baz ='bar';
Functions
function $name$ ($parameters$) {
}
...
|
by: ryjfgjl |
last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
|
by: ryjfgjl |
last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
|
by: emmanuelkatto |
last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud.
Please let me know.
Thanks!
Emmanuel
|
by: BarryA |
last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
|
by: Sonnysonu |
last post by:
This is the data of csv file
1 2 3
1 2 3
1 2 3
1 2 3
2 3
2 3
3
the lengths should be different i have to store the data by column-wise with in the specific length.
suppose the i have to...
|
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
| |