473,387 Members | 1,834 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

Inherit an implementation

17
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:

Expand|Select|Wrap|Line Numbers
  1. #include <cstdio>
  2.  
  3. class IA { public: virtual void m1() = 0; };
  4. class IB: public IA { public: virtual void m2() = 0; };
  5.  
  6. class AImpl: public IA {public: void m1() { printf("m1"); }};
  7. class BImpl: public IB, public AImpl {public: void m2() { printf("m2"); }};
  8.  
  9. int main() { BImpl b; b.m2(); return 0; }
  10.  
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
Nov 13 '08 #1
8 1885
r035198x
13,262 8TB
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.
Nov 13 '08 #2
disown
17
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?
Nov 13 '08 #3
JosAH
11,448 Expert 8TB
What happens when you make those functions 'virtual' in your implementation?

kind regards,

Jos
Nov 13 '08 #4
disown
17
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:
Expand|Select|Wrap|Line Numbers
  1. #include <cstdio>
  2.  
  3. class IA { public: virtual void m1() = 0; };
  4. class IB: public virtual IA { public: virtual void m2() = 0; };
  5.  
  6. class AImpl: public virtual IA { public: virtual void m1() { printf("m1"); } };
  7. class BImpl: public IB, public AImpl { public: void m2() { printf("m2"); } };
  8.  
  9. int main() {
  10.         AImpl a;
  11.         a.m1();
  12.         BImpl b;
  13.         b.m1();
  14.         b.m2();
  15.         return 0;
  16. }
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...
Nov 13 '08 #5
disown
17
Oh, and the extra "virtual" in AImpl::m1 can be removed, I used that to try JosAH's idea.
Nov 13 '08 #6
weaknessforcats
9,208 Expert Mod 8TB
#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().
Nov 13 '08 #7
disown
17
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.
Nov 14 '08 #8
weaknessforcats
9,208 Expert Mod 8TB
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.
Nov 14 '08 #9

Sign in to post your reply or Sign up for a free account.

Similar topics

4
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...
2
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...
6
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...
12
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...
21
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...
2
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...
3
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)
11
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...
2
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; }
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
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$) { } ...
0
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...
0
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...
0
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
0
BarryA
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...
1
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...
0
marktang
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,...
0
jinu1996
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...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.