Topic: Interfaces and C++


Author: girod@dshp01.trs.ntc.nokia.com (Marc Girod)
Date: 1996/09/03
Raw View
>>>>> "HS" == Herb Sutter <herbs@cntc.com> writes:

HS> You have now defined an interface... an abstract base class (ABC) with
HS> no data that defines a behavioural interface.

I fully agree with you that C++ has better interfaces than Java,
precisely because these interfaces may enforce "behaviour" instead of
merely "signature" compatibility.

I may understand by this something slightly different though. Here is
an example of what I mean:

class X {
  public:
    void foo() { bar(); zoo(); }
  protected:
    virtual void bar() = 0;
    virtual void zoo() = 0;
    virtual ~X() {}
};

I.e., I don't much use default implementations. Here, X defines a
protocol foo, and insures that zoo will never be called unless bar has
been called previously.


Is this syntax of yours supported?

HS>      virtual ~foo() = 0 {};

I cannot find any explicit mention of it, and my compiler won't accept
it.

Best Regards!

PS: As for earlier proposals, the "Signatures" proposal, by
Baumgartner and Russo is related, isn't it?
--
Marc Girod                                   Phone:  +358-0-511 27703
Nokia Telecommunications   P.O. Box 12       Fax:    +358-0-511 27432
Kilo RD 4                  FIN-02611 Espoo   marc.girod@ntc.nokia.com
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: "Stephen L. Favor" <sfavor@onramp.net>
Date: 1996/09/03
Raw View
James Kanze US/ESC 60/3/141 #40763 wrote:
>
> In article <3225C9B5.7CFB@mindspring.com> "Donley R. P'Simer"
> <donley@mindspring.com> writes:
>
> |> Has anyone proposed adding interfaces ala Java to the C++ language?
>
> I know that you are going to disagree, but C++ has interfaces that are
> *exactly* like those of Java.  The keyword for declaring an interface is
> "class".  I know that this is also the keyword for declaring a class,

Actually, interface would allow the following, which cannot be done via
subclassing.
The point of an interface is that it says a class must contain some set
of members,
but is not restricted to being based on some class.  The only
implementation of this
functionality I know of in UNIX-land is called a signature and is
available in GCC:

class A { void f(); };
class B { void f(); };
interface I { void f(); };

main()
{
  A *a; = new A;
  B *b = new B;
  I *i = a;
  i->f();
  i = b;
  b->f();
  delete a;
  delete b;
}
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: Alexandre Oliva <oliva@dcc.unicamp.br>
Date: 1996/09/03
Raw View
Jonathan de Boyne Pollard writes:

> Since we are emulating a Java interface, class M cannot exist, since Java
> doesn't have multiple inheritance.   So there's no requirement for virtua=
l
> inheritance when using ABC mixins in C++ to emulate Java interfaces.

Java  does not  have  MI  for   implementation, but THERE  IS  MI  for
interfaces.

So you can have a class B that implements interface I, and C, subclass
of B, that also implements I.  Although  declaring that C implements I
is redundant (it does implement  I by transitivity), a translator  may
not have   information about  B to  decide   that this  declaration is
redundant when translating C.

So, if you translate:

// Java
interface I {}
class B implements I {}
class C extends B implements I {}

to

// C++
class I {};
class B : public I {}
class C : public B, public I {}

you'll  get two instances  of I. However,  if,  instead of "public I",
implements were translated to "public  virtual I", there would only be
one instance of I, which is the correct intent.

--
Alexandre Oliva
oliva@dcc.unicamp.br
Universidade Estadual de Campinas, S=E3o Paulo, Brasil
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: "Roly Perera" <rolyp@private.nethead.co.uk>
Date: 1996/09/03
Raw View
> | If the "interface" class is NOT a virtual base class, you can run into
> | ambiguities. Example:
> |
> |  class Interface {
> |  public:
> |      virtual void foo();
> |  };
> |  class A : public Interface { ... };   // no foo
> |  class B : public Interface { ... };   // no foo
> |  class M : public A, public B { ... }; // no foo
> |  M m;
> |  m.foo(); // error, ambiguous
> |
> | If Interface is a virtual base class, there is no ambiguity.
>
> To quote Steve Clamage, "since we are emulating a Java interface" ...
>
> Since we are emulating a Java interface, class M cannot exist, since Java
> doesn't have multiple inheritance.   So there's no requirement for
virtual
> inheritance when using ABC mixins in C++ to emulate Java interfaces.
>
> Which seems reasonable.  After all, virtual inheritance was only invented
> for C++ to solve some problems with multiple inheritance.  If C++ didn't
> have multiple inheritance, it wouldn't need virtual inheritance either.
So
> it's reasonable that emulating in C++ the features of a language that
only
> supported single inheritance would not require virtual inheritance.

Except that Java _does_ allow multiple inheritance of interfaces!

Roly Perera
----
Interactive Computers Ltd
3 Cumberland Road
Acton
London  W3 6EX
Phone: +44 (956) 414 395
Phax:  +44 (181) 932 2490
Email: rolyp@private.nethead.co.uk
----
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763)
Date: 1996/09/04
Raw View
In article <322B2BF3.5F33@onramp.net> "Stephen L. Favor"
<sfavor@onramp.net> writes:

|> Actually, interface would allow the following, which cannot be done via
|> subclassing.
|> The point of an interface is that it says a class must contain some set
|> of members,
|> but is not restricted to being based on some class.  The only
|> implementation of this
|> functionality I know of in UNIX-land is called a signature and is
|> available in GCC:

|> class A { void f(); };
|> class B { void f(); };
|> interface I { void f(); };

|> main()
|> {
|>   A *a; = new A;
|>   B *b = new B;
|>   I *i = a;
|>   i->f();
|>   i = b;
|>   b->f();
|>   delete a;
|>   delete b;
|> }

Can you do this with Java?  Do G++ signatures allow you to do this?  (I
don't know, I'm really asking.)

I can see several difficulties for an implementation to support this, at
least with dynamic type resolution.  (C++ supports it with static type
resolution, e.g.: through templates.)
--
James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils,    tudes et r   alisations en logiciel orient    objet --
                -- A la recherche d'une activit    dans une region francophone



[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Rich Paul <linguist@cyberspy.com>
Date: 1996/09/04
Raw View
Stephen L. Favor wrote:

> Actually, interface would allow the following, which cannot be done via
> subclassing.
> The point of an interface is that it says a class must contain some set
> of members,
> but is not restricted to being based on some class.  The only
> implementation of this
> functionality I know of in UNIX-land is called a signature and is
> available in GCC:
>
01> class A { void f(); };
02> class B { void f(); };
03> interface I { void f(); };
04>
05> main()
06> {
07>   A *a; = new A;
08>   B *b = new B;
09>   I *i = a;
10>   i->f();
11>   i = b;
12>   b->f();
13>   delete a;
14>   delete b;
15> }

if you delete line 3, and insert before line 1 a line:
 class I { virtual void f() = 0; };

you have the same thing ... I'm assuming that you left the 'implements'
out of classes A and B in error, so add it and then change it to public.

Where is the improvement in your sample as opposed to mine?

--
#include <legalbs/standarddisclaimer>
Rich Paul                |  If you like what I say, tell my
C++, OOD, OOA, OOP,      |  employer, but if you don't,
OOPs, I forgot one ...   |  don't blame them.  ;->


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: girod@dshp01.trs.ntc.nokia.com (Marc Girod)
Date: 1996/09/04
Raw View
>>>>> "SF" == "Stephen L Favor" <sfavor@onramp.net> writes:

SF> Actually, interface would allow the following, which cannot be done via
SF> subclassing.

"Signatures" are only generic. They should not be called interfaces,
since they are much weaker than C++ ABC interfaces (which can specify
behaviour as well).

Your example may be written in standard C++:

struct A { void f(); };
struct B { void f(); };
template <class T> void apply_f(T* t) { t->f(); }

int main() {
  A *a = new A;
  B *b = new B;
  apply_f(a);
  apply_f(b);
  delete a;
  delete b;
}

Best Regards!
--
Marc Girod                                   Phone:  +358-0-511 27703
Nokia Telecommunications   P.O. Box 12       Fax:    +358-0-511 27432
Kilo RD 4                  FIN-02611 Espoo   marc.girod@ntc.nokia.com


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: JdeBP@jba.co.uk (Jonathan de Boyne Pollard)
Date: 1996/09/04
Raw View
Alexandre Oliva (oliva@dcc.unicamp.br) wrote:
| Jonathan de Boyne Pollard writes:
|
| > Since we are emulating a Java interface, class M cannot exist, since Java
| > doesn't have multiple inheritance.   So there's no requirement for virtual
| > inheritance when using ABC mixins in C++ to emulate Java interfaces.
|
| [...] if you translate:
|
| // Java
| interface I {}
| class B implements I {}
| class C extends B implements I {}
|
| to
|
| // C++
| class I {};
| class B : public I {}
| class C : public B, public I {}
|
| you'll  get two instances  of I.

Nevertheless, this doesn't actually matter.  There's no requirement to use
virtual inheritance here, since there isn't a problem here that virtual
inheritance solves.  In fact, there isn't a problem here, full stop.

This is because I is an Abstract Base Class mixin without any data members.
That is, it only has pure virtual function members.  In C++ any overrider in
class C will override the virtual functions in *both* instances of I.  So it
doesn't matter *which* I is used as the "interface", since there is only
one final overrider function at runtime.

Or, in other words

 class I { public: virtual void f() = 0 ; } ;
 class B : public I {}
 class C : public B, public I { public: virtual void f() ; }

 C c ;
 I * i1 = (I *)(B *)&c ;
 I * i2 = (I *)&c ;

 i1->f() ; // Calls C::f through the first "interface"
 i2->f() ; // Calls C::f through the second "interface"

No need for virtual inheritance.
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: "Stephen L. Favor" <sfavor@onramp.net>
Date: 1996/09/07
Raw View
Rich Paul wrote:

> 01> class A { void f(); };
> 02> class B { void f(); };
> 03> interface I { void f(); };
..........
> if you delete line 3, and insert before line 1 a line:
>         class I { virtual void f() = 0; };
>
> you have the same thing ... I'm assuming that you left the 'implements'
> out of classes A and B in error, so add it and then change it to public.

Almost, but not precisely.  Signatures in gcc and implementation in java
provide a way to specify what function members are present independent
of
a class hierarchy.

> Where is the improvement in your sample as opposed to mine?

For more information as to why, see the author's summary in
ftp://ftp.cs.purdue.edu/pub/gb/README.  There are also
a couple of papers in ftp://ftp.cs.purdue.edu/pub/gb that discuss the
academics
of why.

Also, gcc signatures and java interfaces have some significant
differences as someone
else has noted.

steve
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: clamage@taumet.eng.sun.com (Steve Clamage)
Date: 1996/08/29
Raw View
In article 7CFB@mindspring.com, "Donley R. P'Simer" <donley@mindspring.com> writes:
>Has anyone proposed adding interfaces ala Java to the C++ language? I
>think they would be a great addition. There have been many times that I
>have wanted to group classes by a set of possible operations without
>associating them by inheritance, or present different interfaces to the
>same class to different modules. Maybe something like this:
>
>-----------------------------
>foo.h:
>-----------------------------
>interface foo
>{
>public:
>   void fubar();
>   int snafu();
>};
>
>-----------------------------
>bar.h:
>-----------------------------
>#include "foo.h"
>class bar : implements foo
>{
>public:
>   bar();
>   ~bar();
>
>   // I don't know if it would be necessary to redeclare the
>   // members of an implemented interface here. It might be
>   // optional but recommended for documentation purposes.
>   void fubar();
>   int snafu();
>};

I don't see how Java interfaces differ from C++ virtual base
classes without data. For example, replacing only the keywords
"interface" and "implements", we would have this:

foo.h:
-----------------------------
class foo {
public:
   void fubar();
   int snafu();
};

bar.h:
-----------------------------
#include "foo.h"
class bar : virtual public foo {
   bar();
   ~bar();
};

In this example we inherit the fubar and snafu from foo, but we could
replace them in bar. We could also make fubar and/or snafu virtual
functions, in which case clients that know only about foo could still
get the functionality of an overriding bar::fubar or bar::snafu.

The difference from Java is that C++ is more flexible. In Java,
all class objects are on the heap, and every declared "object" is
really a reference. You always can get polymorphism without using
reference or pointer notation (Java doesn't have pointers), since
you don't have the option of creating a distinction between an
object and a reference to that object. (Java is simpler and cleaner
than C++ in this respect, but there can be performance penalties.)

Java doesn't have multiple inheritance or virtual base classes.
It seems to me that "interfaces" are a way to provide a limited
amount of that functionality without opening up the problems of MI.

Maybe I've missed something, but I don't see that interfaces provide
any convenience or functionality we don't already have in C++.

---
Steve Clamage, stephen.clamage@eng.sun.com




[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Donley R. P'Simer" <donley@mindspring.com>
Date: 1996/08/29
Raw View
Has anyone proposed adding interfaces ala Java to the C++ language? I
think they would be a great addition. There have been many times that I
have wanted to group classes by a set of possible operations without
associating them by inheritance, or present different interfaces to the
same class to different modules. Maybe something like this:

-----------------------------
foo.h:
-----------------------------
interface foo
{
public:
   void fubar();
   int snafu();
};

-----------------------------
bar.h:
-----------------------------
#include "foo.h"
class bar : implements foo
{
public:
   bar();
   ~bar();

   // I don't know if it would be necessary to redeclare the
   // members of an implemented interface here. It might be
   // optional but recommended for documentation purposes.
   void fubar();
   int snafu();
};

And now I can do things like this:

-----------------------------
func1.cpp:
-----------------------------
#include "foo.h"
void func1(foo* pFoo)
{
   while (pFoo->snafu() != 0)
      pFoo->fubar();
}

func1() is in a module that doesn't know about any of the classes that
have implemented foo.

-----------------------------
func1.cpp:
-----------------------------
#include "foo.h"
#include "bar.h"
void func1(foo*);

int func2()
{
   bar theBar;
   func1(&theBar);
}

I know that some will say that multiple inheritance accomplishes the
same thing, but I disagree. I have tried to use multiple inheritance to
do the things I mentioned above, but it just doesn't work well. Multiple
inheritance solves a different set of problems than interfaces.

Comments?

 Donley R. P'Simer


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: clamage@taumet.eng.sun.com (Steve Clamage)
Date: 1996/08/30
Raw View
In article 27337288@news.interlog.com, herbs@cntc.com (Herb Sutter) writes:
>On 29 Aug 1996 22:40:50 GMT, clamage@taumet.eng.sun.com (Steve
>Clamage) wrote:
>>In article 7CFB@mindspring.com, "Donley R. P'Simer" <donley@mindspring.com> writes:
>>>Has anyone proposed adding interfaces ala Java to the C++ language? I
>[snip]
>
>>class foo {
>>public:
>>   void fubar();
>>   int snafu();
>>};
>[snip]
>>#include "foo.h"
>>class bar : virtual public foo {
>>   bar();
>>   ~bar();
>>};
>>
>>In this example we inherit the fubar and snafu from foo, but we could
>>replace them in bar. We could also make fubar and/or snafu virtual
>>functions, in which case clients that know only about foo could still
>>get the functionality of an overriding bar::fubar or bar::snafu.
>
>I agree in general (though to make it work the way the original poster
>wanted the functions must be declared virtual in the base class), but
>why choose virtual inheritance?  There's no data anyway, and at any
>rate I tend to avoid virtual inheritance unless absolutely necessary
>because of the burden it puts on all derived classes, since every
>derived class ctor must correctly call the (proper, if several) VBC
>ctor.

Since we are emulating a Java interface, the "interface" class has no
base classes, and no data. Therefore it needs no declared
constructor or destructor. Thus no derived class has to care about
constructors for the virtual base class acting as an interface.

If the "interface" class is NOT a virtual base class, you can run into
ambiguities. Example:

 class Interface {
 public:
     virtual void foo();
 };
 class A : public Interface { ... };   // no foo
 class B : public Interface { ... };   // no foo
 class M : public A, public B { ... }; // no foo
 M m;
 m.foo(); // error, ambiguous

If Interface is a virtual base class, there is no ambiguity.

Depending on how the interface class is used, whether it is virtual
might not matter. But I don't think adopting the convention
of always making it virtual can cause any problems.
---
Steve Clamage, stephen.clamage@eng.sun.com




[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: herbs@cntc.com (Herb Sutter)
Date: 1996/08/30
Raw View
On 29 Aug 1996 22:40:50 GMT, clamage@taumet.eng.sun.com (Steve
Clamage) wrote:
>In article 7CFB@mindspring.com, "Donley R. P'Simer" <donley@mindspring.com> writes:
>>Has anyone proposed adding interfaces ala Java to the C++ language? I
[snip]
>>interface foo
>>{
>>public:
>>   void fubar();
>>   int snafu();
>>};

Change this to:

  class foo
  {
  public:
     virtual void fubar() = 0
         { /* optional default implementation, put body in .CPP */ };
     virtual int  snafu() = 0
         { /* optional default implementation, put body in .CPP */ };
  protected:                // out of habit, good style
     virtual ~foo() = 0 {}; // out of habit, good style
  };

You have now defined an interface... an abstract base class (ABC) with
no data that defines a behavioural interface.  This is a common method
(at least, I use it all the time).  I make it pure virtual to ensure
the ABC can't be instantiated, but as shown you can even go ahead and
provide default implementations if you want.  Then what you do is mix
this interface into whatever classes want to support it:

>>#include "foo.h"
>>class bar : implements foo
>>{
>>public:
[snip]
>>   void fubar();
>>   int snafu();
>>};

Change this to:

  class bar : public foo
  {
      void fubar();
      int  snafu();
  };

Voila!  bar implements the interface specified by foo.  You can now
use it as you wanted to, say by declaring a function that takes a foo*
and at runtime pass it a bar*.  Works like a charm.  Very useful
idiom.

Steve responded by proposing:

>class foo {
>public:
>   void fubar();
>   int snafu();
>};
[snip]
>#include "foo.h"
>class bar : virtual public foo {
>   bar();
>   ~bar();
>};
>
>In this example we inherit the fubar and snafu from foo, but we could
>replace them in bar. We could also make fubar and/or snafu virtual
>functions, in which case clients that know only about foo could still
>get the functionality of an overriding bar::fubar or bar::snafu.

I agree in general (though to make it work the way the original poster
wanted the functions must be declared virtual in the base class), but
why choose virtual inheritance?  There's no data anyway, and at any
rate I tend to avoid virtual inheritance unless absolutely necessary
because of the burden it puts on all derived classes, since every
derived class ctor must correctly call the (proper, if several) VBC
ctor.

>Maybe I've missed something, but I don't see that interfaces provide
>any convenience or functionality we don't already have in C++.

I too would be interested to find out whether Java interfaces offer
something that can't be done with either pure virtual ABC mixins or
templates.

Herb

---
Herb Sutter (herbs@cntc.com)

Current Network Technologies Corp.
3100 Ridgeway, Suite 42, Mississauga ON Canada L5L 5M5
Tel 416-805-9088  Fax 905-608-2611


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763)
Date: 1996/08/30
Raw View
In article <199608301527.IAA00640@taumet.eng.sun.com>
clamage@taumet.eng.sun.com (Steve Clamage) writes:

|> In article 27337288@news.interlog.com, herbs@cntc.com (Herb Sutter) writes:
|> >I agree in general (though to make it work the way the original poster
|> >wanted the functions must be declared virtual in the base class), but
|> >why choose virtual inheritance?  There's no data anyway, and at any
|> >rate I tend to avoid virtual inheritance unless absolutely necessary
|> >because of the burden it puts on all derived classes, since every
|> >derived class ctor must correctly call the (proper, if several) VBC
|> >ctor.

|> Since we are emulating a Java interface, the "interface" class has no
|> base classes, and no data. Therefore it needs no declared
|> constructor or destructor.

What about if the user deletes the object through a pointer to the
interface class.  I appreciate your comments about making the
inheritance virtual; I'd not considered this aspect before.  But surely
you aren't suggesting that we publicly derive from a class without a
virtual destructor.
--
James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils,    tudes et r   alisations en logiciel orient    objet --
                -- A la recherche d'une activit    dans une region francophone
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: JdeBP@jba.co.uk (Jonathan de Boyne Pollard)
Date: 1996/08/30
Raw View
Steve Clamage (clamage@taumet.eng.sun.com) wrote:
| Since we are emulating a Java interface, the "interface" class has no
| base classes, and no data. Therefore it needs no declared
| constructor or destructor. Thus no derived class has to care about
| constructors for the virtual base class acting as an interface.
|
| If the "interface" class is NOT a virtual base class, you can run into
| ambiguities. Example:
|
|  class Interface {
|  public:
|      virtual void foo();
|  };
|  class A : public Interface { ... };   // no foo
|  class B : public Interface { ... };   // no foo
|  class M : public A, public B { ... }; // no foo
|  M m;
|  m.foo(); // error, ambiguous
|
| If Interface is a virtual base class, there is no ambiguity.

To quote Steve Clamage, "since we are emulating a Java interface" ...

Since we are emulating a Java interface, class M cannot exist, since Java
doesn't have multiple inheritance.   So there's no requirement for virtual
inheritance when using ABC mixins in C++ to emulate Java interfaces.

Which seems reasonable.  After all, virtual inheritance was only invented
for C++ to solve some problems with multiple inheritance.  If C++ didn't
have multiple inheritance, it wouldn't need virtual inheritance either.  So
it's reasonable that emulating in C++ the features of a language that only
supported single inheritance would not require virtual inheritance.
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: michaelt@asymetrix.com (Michael Taylor)
Date: 1996/08/30
Raw View
clamage@taumet.eng.sun.com (Steve Clamage) wrote:
>Since we are emulating a Java interface, the "interface" class has no
>base classes, and no data. Therefore it needs no declared
>constructor or destructor. Thus no derived class has to care about
>constructors for the virtual base class acting as an interface.

>If the "interface" class is NOT a virtual base class, you can run into
>ambiguities. Example:

> class Interface {
> public:
>     virtual void foo();
> };
> class A : public Interface { ... };   // no foo
> class B : public Interface { ... };   // no foo
> class M : public A, public B { ... }; // no foo
> M m;
> m.foo(); // error, ambiguous

I missed the original posts in this thread, so maybe I missing
something.

Since we are emulating a Java interface shouldn't all the methods in
Interface be pure? Then wouldn't

 M m;

fail to compile.

Michael Taylor (michaelt@asymetrix.com)
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763)
Date: 1996/08/30
Raw View
In article <3225C9B5.7CFB@mindspring.com> "Donley R. P'Simer"
<donley@mindspring.com> writes:

|> Has anyone proposed adding interfaces ala Java to the C++ language?

I know that you are going to disagree, but C++ has interfaces that are
*exactly* like those of Java.  The keyword for declaring an interface is
"class".  I know that this is also the keyword for declaring a class,
but this wouldn't be the first time that C++ (or C) used the same
keyword for different things:-).  (Actually, in this case, I think that
it is Java which is using two different words for what is basically the
same thing.)

|> I
|> think they would be a great addition. There have been many times that I
|> have wanted to group classes by a set of possible operations without
|> associating them by inheritance, or present different interfaces to the
|> same class to different modules. Maybe something like this:

|> -----------------------------
|> foo.h:
|> -----------------------------
|> interface foo
|> {
|> public:
|>    void fubar();
|>    int snafu();
|> };

In C++,

 class foo
 {
 public:
  void fubar() = 0 ;
  int snafu() = 0 ;
 } ;

As far as I can see (I don't know that much about Java), the only thing
that is happening in Java is that declaring something "interface" rather
than class makes all of the functions pure virtual.  In C++, you have to
do this on a function by function basis.

|> -----------------------------
|> bar.h:
|> -----------------------------
|> #include "foo.h"
|> class bar : implements foo
               ^^^^^^^^^^

In C++, the keyword here is "public".

|> {
|> public:
|>    bar();
|>    ~bar();

|>    // I don't know if it would be necessary to redeclare the
|>    // members of an implemented interface here. It might be
|>    // optional but recommended for documentation purposes.
|>    void fubar();
|>    int snafu();

In C++, they must be declared.  I don't know the situation in Java, but
I cannot imagine how you could avoid declaring them in the class where
they are implemented.  (Note that in fact, they don't need to be
declared here in C++ if they are to be implemented only in a class
derived from bar.)

|> };

|> And now I can do things like this:

|> -----------------------------
|> func1.cpp:
|> -----------------------------
|> #include "foo.h"
|> void func1(foo* pFoo)
|> {
|>    while (pFoo->snafu() != 0)
|>       pFoo->fubar();
|> }

|> func1() is in a module that doesn't know about any of the classes that
|> have implemented foo.

This works exactly the same way in C++, modulo the changes in the
keyword, and the fact that each function must be declared pure virtual
separately.

|> -----------------------------
|> func1.cpp:
|> -----------------------------
|> #include "foo.h"
|> #include "bar.h"
|> void func1(foo*);

|> int func2()
|> {
|>    bar theBar;
|>    func1(&theBar);
|> }

|> I know that some will say that multiple inheritance accomplishes the
|> same thing, but I disagree. I have tried to use multiple inheritance to
|> do the things I mentioned above, but it just doesn't work well. Multiple
|> inheritance solves a different set of problems than interfaces.

Multiple inheritance solves a superset of the problems solved by
interfaces.  As far as I can see, the only difference (except for the
spelling of the keywords) is that in C++, each individual function must
be declared pure virtual, whereas in Java, if the keyword "interface" is
used instead of "class", all of the functions are automatically declared
virtual.  (Question: can you have private functions in an "interface"?
I cannot see where they would make much sense.  Private pure virtual
functions in C++ are useful because they can be called from a public
non-pure-virtual member function.)

Could you please clarify why multiple inheritance doesn't work well in
the above case, and what is different in an "interface" that makes it
better.
--
James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils,    tudes et r   alisations en logiciel orient    objet --
                -- A la recherche d'une activit    dans une region francophone
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: herbs@cntc.com (Herb Sutter)
Date: 1996/08/31
Raw View
On 30 Aug 1996 13:39:39 PDT, JdeBP@jba.co.uk (Jonathan de Boyne
Pollard) wrote:

>Steve Clamage (clamage@taumet.eng.sun.com) wrote:
>| Since we are emulating a Java interface, the "interface" class has no
>| base classes, and no data. Therefore it needs no declared
>| constructor or destructor. Thus no derived class has to care about
>| constructors for the virtual base class acting as an interface.
>|
>| If the "interface" class is NOT a virtual base class, you can run into
>| ambiguities. Example:
>|
>|  class Interface {
>|  public:
>|      virtual void foo();
>|  };
>|  class A : public Interface { ... };   // no foo
>|  class B : public Interface { ... };   // no foo
>|  class M : public A, public B { ... }; // no foo
>|  M m;
>|  m.foo(); // error, ambiguous
>|
>| If Interface is a virtual base class, there is no ambiguity.
>
>To quote Steve Clamage, "since we are emulating a Java interface" ...
>
>Since we are emulating a Java interface, class M cannot exist, since Java
>doesn't have multiple inheritance.   So there's no requirement for virtual
>inheritance when using ABC mixins in C++ to emulate Java interfaces.

Yes, but Steve's quite right in correcting me... I didn't realise that
the absence of a user-defined ctor eliminated the need for derived
class ctors to call the virtual base class ctor.

Interestingly, as Steve pointed out, while this may have begun with
"emulating a Java interface," we should write the C++ version in a way
that's equivalent to the original Java intent even for the cases Java
doesn't support but which C++ does (namely MI).

---
Herb Sutter (herbs@cntc.com)

Current Network Technologies Corp.
3100 Ridgeway, Suite 42, Mississauga ON Canada L5L 5M5
Tel 416-805-9088  Fax 905-608-2611


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]