Ryan's District
November 22, 2008, 02:31:30 PM *
Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
News: Ryan's District Lottery: Claim your ticket or check
Jackpot details  
 
   Home   Help Search Chat Calendar Chess Shop Login Register  
Digg This!
Pages: [1]   Go Down
  Send this topic  |  Print  
Author Topic: C++ tips - Abstract, concrete, and value semantics  (Read 2461 times)
0 Members and 1 Guest are viewing this topic.
ben2ong2
Quality Poster
Paid
Hero Member
*****

Reputation: 17
Offline Offline

Gender: Male
Posts: 2374
9976.80 RD$

View Inventory
Send Money to ben2ong2

View Profile Awards
« on: October 07, 2006, 08:44:42 AM »

PROBLEM: shansen@adobe.com (Steve Hansen), Adobe, 3 May 93

[A]

In this month's Byte magazine, Allen Holub makes some good points warning
against creating a root abstract class (e.g. Collection) upon which
everything else is derived, on the basis that it makes it more
difficult to create hybrid classes via multiple inheritance.  For those
who haven't read the article, Holub points out that if you try to
merge two classes via MH that have a common root class, then the
compiler will complain about the ambiguity. 



He thus recommends
dispensing with the formality of using the abstract class, i.e.
go ahead and define a common interface for your classes, but don't
create the abstract class a la Smalltalk.  I would like to hear
people's opinions on this.

[C]

Are there really that many cases where you want to code at the
generic level, using the abstract class blindly as your data type?

[D]

I have a bad feeling that this debate has been hashed out already,
but I thought I'd try anyway.


RESPONSE: maxtal@physics.su.OZ.AU (John Max Skaller), 3 May 93

[A]
   From your description, this is wrong. The compiler does not
get mixed up because you used *virtual* inheritance, didnt you :-)


   IMHO the wrong conclusion is drawn. The correct conclusion
is not to create Object Heirarchies. At all. They dont work.
Do not use public nonvirtual derivation to specialise a concrete
class unless you make the copy constructor of the root private.

[C]
   Yes. In C++ if you dont use abstract classes you are probably not
doing object oriented programming. OOP is not everything, but
it is sometimes a bit useful :-)

[D]
   In C++, reusing the interface of a class and reusing
the code of a class are very often in conflict.

   The way to resolve this seems to be to separate the
interface from the code. That is, to make separate abstract
and concrete classes:

   struct AbstractThing {
      virtual int func()=0;
   };

   struct ConcreteThing : public virtual AbstractThing {
      int func();
   };
      
Now, if you want to specialise, you do this:

   struct SpecialAbstractThing : public virtual AbstractThing {
      virtual int special()=0;
   };

and implement with say:

   struct SpecialConreteThing : public virtual SpecialAbstractThing
   {
      int func();
      int special();
   };

Notice that the SpecialConcreteThing is NOT derived from the ConreteThing.
There is interface reuse, but no code reuse. You want to reuse some
code? OK:

   struct SpecialConceteThing
   :
      public virtual SpecialAbstractThing,
      private ConcreteThing
   {
      int special();
   };

Its important that the derivation for code reuse be private.
Reusing interface and reusing code are separate and hard to mix.
(You can do it as above, which is a "mixin" of sorts).

The way you should NOT design this code is like this:

   struct ConreteThing {
      int x;
      virtual int func(){return x; }
   };

   struct SpecialConcreteThing : public ConcreteThing
   {
      int y;
      virtual int special() {return y;}
   };

This confuses reuse of the interface and reuse of the code:
it does both together and pretends that a SpecialConcreteThing 'isA'
Concrete thing .. which is not true.

   Given:

   ConcreteThing * it = new SpecialConcreteThing;

how do you call 'special'? You cant without downcasting and RTTI.
On the other hand, you cant usually safely use an actual known
SpecialConcreteThing as a ConcreteThing either:

   SpecialConreteThing spit;
   func(ConcreteThing x);
   func(spit); // woops, sliced off the 'special' part

   refunc(ConcreteThing& x);
   refunc(spit); // woops, cant access the 'special' part

Logged

You are not allowed to view links.
Register or Login
Free Paid Survey & Home Business Resources.

You are not allowed to view links.
Register or Login
Free Article Directory | Quality Content
Ryan's District
« on: October 07, 2006, 08:44:42 AM »

 Logged
Pages: [1]   Go Up
  Send this topic  |  Print  
 
Jump to:  

Archive - WAP2 - WAP - imode
Sponsors: RAYAN.tv
-

Powered by MySQL Powered by PHP Powered by SMF 1.1.7 | SMF © 2006-2008, Simple Machines LLC Valid XHTML 1.0! Valid CSS!
Page created in 8.116 seconds with 30 queries.

Google visited last this page Today at 04:24:28 AM