From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-0.3 required=5.0 tests=BAYES_00, REPLYTO_WITHOUT_TO_CC autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 109fba,9ac62ca34a465706,start X-Google-Attributes: gid109fba,public X-Google-Thread: 103376,9ac62ca34a465706,start X-Google-Attributes: gid103376,public From: nabbasi@qualcomm.com (Nasser Abbasi) Subject: on OO differnces between Ada95 and C++ Date: 1996/02/20 Message-ID: <4gbq7q$g08@qualcomm.com> X-Deja-AN: 140230191 organization: QUalcomm Inc. reply-to: x!news.be.innet.net!INbe.net!usenet newsgroups: comp.lang.ada,comp.lang.c++ Date: 1996-02-20T00:00:00+00:00 List-Id: Hello, I have a simple comment, but probably a long way of showing it :) I have been playing around with the OO features in Ada95 and comparing it with C++. I noticed this little difference, and I'd like to see what you think of it. Lets assume we have a base class called Account, and a class called Saving_Account that uses Account as base. Lets also assume that we need to define a Money Type, defined in the base class Account. In Ada95 this type is defined in the package Account.ads that also includes the definition of the tagged record type Account (along with operations that act on Account type). In C++, this Money Type is typedef'ed inside the public part of the class Account, and it becomes part of the public interface of the base class. so far so good. Now, In Ada95, a client that wishes to use Saving_Account type (and any operations on it) will "with" the Saving_Account Package. Also, in C++, a client who wishes to use Saving_Account class will include "saving_account.h" There is some differences though. In C++, the client to the saving_account class can also use the Money_Type type (even though that is defined in the base class Account) without having to include base class "account.h", this is because Money_Type has become a public part of the Saving_Account class when Saving_Account inherited Saving class. In Ada95, the client of Saving_Account has no viability to Money_Type type definition even though they with'ed Saving_account package, since Money_Type is not a "inherited" by the Saving_Account package from the Account package. This means that in Ada95, If one wants to access things like type definitions that are not tagged, but used in defining components inside the tagged record, one must "with" the client package and also packages that the client package with'ed just to be able to have viability to those type definitions. I understand the reason why in Ada95 one must do this, a client "with"ing a package has only viability to the public part of that package and not to any packages that that package may have "with"ed. In this case, It seems the C++ way of having everything inside the public base class becoming visible to clients of the derived class that inherits the base class is more economical?. (everything means, data members, methods members and things like enum, typedefs, structs. etc..) In Ada95 only certain type (the tagged record type) and methods on this type can be seen by clients of the extended type. One way to go around having in Ada95 to "with" both Account and Saving_Account packages, is that in the Saving_Account package to introduce new type Money_Type made of the Account.Money_Type, this way clients of Saving_Account can see Money_Type type by just "with"ing Saving_Account package and not have to "with" account package also just to use the Money_Type. But this means that type definitions has to be manually "propagated" from one package to another so that clients of the last package in the chain have only to "with" that last package. Any better way? Just to put all this in example, (In case the above got to winded :) , I have an example to show I mean. I show the Ada code, and below it the C++ code. You see that in Ada, the main.adb had to "with" both Account and Saving_account, while in C++, the main had to only include "saving_account.h" . thanks, Nasser Learning_Ada95_OO_features... ------------------ account.ads --------------------------- package Account is type Money_Type is new integer range 1..100; -- just as an example type Account_Type is tagged record Balance : Money_Type; Account_Id : Integer; end record; end Account; ----------------- saving_account.ads ---------------- with Account; Package Saving_Account is type Saving_Account_Type is new Account.Account_Type with record Interest : Account.Money_Type; end record; -- here we could also type this: -- -- Type Money_Type is new Account.Money_Type -- -- this way Money_Type can be made visible to clients -- of saving account without having to "with" Account package. -- we have propogated Money_Type to this package from the -- "with"ed package, so that clients to this package can see -- this type without having to "with" the Account package -- JUST to access Money_Type -- end Saving_Account; --------------- main.adb --------------------------- with Account; -- only reason with'ed is to have visibility to -- money_type. in C++, the main can see the Money_Type -- through Saving_Account, and do not have to include -- the base class Account with Saving_Account; with ada.text_io; use ada.text_io; procedure main is package Money_IO is new Ada.Text_IO.Integer_IO(Account.Money_Type); The_Saving_Account : Saving_Account.Saving_Account_Type; The_Balance : Account.Money_Type; begin Money_IO.Get(The_Balance); The_Saving_Account.Balance := The_Balance; end main; ============================== Now the C++ way: --------------- account.h ------------------- class Account { public: typedef int Money_Type; Money_Type Balance; int Account_Id; }; -------------- saving_account.h ----------------- #include "saving_account.h" class Saving_Account : public Account { public: Money_Type Interest; }; --------------- main.cpp ----------------- #include #include "saving_account.h" // Notice: no need to include to base class // Account in account.h main() { Saving_Account The_Saving_Account; Saving_Account::Money_Type The_Balance; // notice, Money_Type accessed // through Saving_Account and // no need to include the // base class account cout << "Balance?"; cin >> The_Balance; The_Saving_Account.Balance = The_Balance; return 1; }