Re: Interfaces in C++
On Oct 9, 11:36 am, ytrem...@nyx.nyx.net (Yannick Tremblay) wrote:
In article <1223538478.762...@vasbyt.isdsl.net>,
Chris Becke <chris.be...@gmail.com> wrote:
XPCom is little more than a pillage of Microsoft COM. Both,
at their base level consist of declaring a C++ class
containing pure virutal methods and compiling with a
compatible compiler. Ensuring that even c++ interfaces
intended to be used only by homogeneous (c++) code are
nonetheless compatible at a binary level means that code can
easilly move from a homogeneous to a heterogeneous
environment.
Fine. But it has costs. For example:
- potential bugs due to multiple inheritance.
- slower development. Instead of using native C++ techniques, you
waste time jumping through hoops to ensure universal binary level
compatibility.
I'm having problems figuring out what virtual inheritance has to
do with all this. Certainly, some languages might not support
it. But then, many of the most widely used languages outside of
C++ (e.g. Cobol, C) don't even support inheritance to begin
with.
If there is really a requirement that your component be usable
from other languages, then the best (most flexible) solution is
to define an interface for it using Corba, or something similar.
But that's normally just a facade, used to map your internal
interfaces (which are pure C++) to the outside world.
If your not really concerned about portability, and limit
yourself to the Unix/Windows world, and you're 100% sure that
the interface will never be called from another process
(possibly running on another machine), you can probably get away
with just making everything "C compatible".
And special cases require special solutions; if your component
must be called from Java, you'll implement the interface
according to JNI.
(I'm not familiar with COM, since I've never seen anyplace which
actually used it, but I think it falls somewhere between the
last two cases---probably closer to JNI than anything else.)
Which is just good software engineering practice.
If it is needed. You gorget a number of other "good software
engiinering practices" such as KISS, YAGNI and TANSTAAFL.
Not to mention that you'll want to test it. Until you've tested
that the component really can be called from Cobol, you have to
suppose that it can't be called from Cobol, regardless of the
"rules" you've supposedly followed.
Rejecting multiple inheritance on the grounds that by doing so,
your code will somehow miraculously be callable from another
language is just plain ignorant. The basic premise is false.
Not everyone uses c++. .so and .dll files are (depending on
your platform) common ways to glue binary files (from teams
with different toolsets) together .
True. But two things: not everyone need C++ to offer binary
level compatibility with other languages.
And no one has to offer it at all levels. At the most, you
offer it at the component level, for a pre-defined subset of
languages, using a pre-defined technology (e.g. Corba). And you
implement it using the facade pattern. (But I see you've more
or less hit on that on what followed.)
And most importantly, switch of languages like that should be
at (large) module boundaries. These modules boundaries should
have narrow and very well defined interfaces. So it is a
relatively trivial job to ensure that interface that are meant
to be used accross different language do offer an appropriate
binary compatible interface but for the rest, you should use
safe coding practices.
The virtual keyword prevents that interface and any derived
interfaces ever being exported in a binary compatible way
(on compilers that otherwise produce interfaces in a way that
DOES conform to COM/XPComs binary interface requirements). If
you are developing reusable code you can never know how its
going to need to be used in the future. don't shoot yourself
in the foot and rely on this broken mechanism. It might be
good "c++". but its bad computer science. It violates the
earliest principals computer science students are taught
about avoiding coupling.
Bull*****. That is not "avoiding coupling" you are preaching
at all.
It's actually imposing an artificial coupling. Your code is
100% coupled to one particular technique of communicating
between components. Not a widely used one, either, from what I
can see.
What you are saying is that no interface should use
std::string, we should all revert back to the good old days of
bare buffer pointers because maybe someone somewhere might
possibly want to reuse our code in a way that is not C++
compatible and won't be able to access std::string. Who
cares about buffer overflow, crashing applications and speed
of development, we must only use universally compatible
constructs in all interfaces that exist!
Facts:
- Not using virtual inheritance is dangerous in the case of multiple
inheritance
- Using virtual inheritance can break XPCOM binary requirements.
Solution:
Use virtual inheritance by default and use non-virtual in
public, exported to other language, XPCOM interfaces.
That seems very clear and simple to me.
Exactly. Design and develop your component cleanly, then
provide whatever facades are needed to interface with whatever
is required.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34