home *** CD-ROM | disk | FTP | other *** search
- Xref: sparky comp.lang.c++:12428 comp.object:3228 comp.databases:6155
- Path: sparky!uunet!europa.asd.contel.com!darwin.sura.net!Sirius.dfn.de!math.fu-berlin.de!news.netmbx.de!Germany.EU.net!mcsun!sunic!seunet!appli!niklas
- From: niklas@appli.se (Niklas Hallqvist)
- Newsgroups: comp.lang.c++,comp.object,comp.databases
- Subject: Re: A POET Tutorial
- Keywords: OODBMS, C++, POET
- Message-ID: <2008@appli.se>
- Date: 14 Aug 92 07:44:36 GMT
- References: <TCZ5DU@netmbx.netmbx.de> <9222615.24974@mulga.cs.mu.OZ.AU> <HH150DN@netmbx.netmbx.de>
- Followup-To: comp.lang.c++
- Organization: Applitron Datasystem AB, GOTHENBURG, SWEDEN
- Lines: 85
-
- jrobie@netmbx.netmbx.de (Jonathan Robie) writes:
-
- >fjh@mundil.cs.mu.OZ.AU (Fergus James HENDERSON) writes:
-
- >>I have a couple of questions regarding Jonathan Robie's posting:
-
- >>> objbase.Close();
- >>> objbase.DisConnect();
-
- >>Why aren't Close() and DisConnect() automatically called by the
- >>destructor?
-
- >Each of these returns error codes which the programmer might want
- >to test and respond to.
-
- It's true that you should provide means for a user to intercept errors
- but making resource deallocation explicit just for this may introduce
- errors instead. The programmer might easily forget such a deallocation.
- Studies have shown that almost all non-trivial programs developped without
- a debugging malloc leaks memory, so it's not an uncommon error. How should
- it be done then? Well, one way is to do what Bjarne did with "new",
- introduce an error_handler pointer which the user can direct to his own code,
- another will be: use exceptions. But beware... the latter can really
- surprise you in destructor contexts like these. I'd go for the error_handler
- to start with.
-
- >>> PersonAllSet* allPersons = new PersonAllSet("objbase");
- >>> Person* thisPerson;
- >>>
- >>> allPersons->Seek(0, PtSTART);
- >>> while (allPersons->Seek (1, PtCURRENT) == 0)
- >>> {
- >>> allPersons->Get(thisPerson);
- >>> thisPerson->DoSomething();
- >>> allPersons->Unget(thisPerson); // deletes the object if nobody
- >>> // else is using it.
- >>> }
- >>> delete allPersons;
- >>>
- >>>[...]
- >>>Note that we call Unget() when we are done with the object. Every
- >>>object you read takes up memory, so you should get into this habit.
-
- >>Again, weren't destructors invented so that we wouldn't have to rely
- >>on programmers habits?
-
- >What destructors are you talking about? The destructor for allPersons
- >is not a good candidate, since it may sit around for a long time
- >creating objects that you really don't want to keep in memory until
- >the set is deleted, and using this destructor would make us keep
- >track of all loaded objects in the allPersons set.
-
- >The destructor for the object is also not a great candidate since
- >it depends on programmer's habits just as much as the Unget() and
- >has different semantics.
-
- I think he was thinking of an auxiliary resource allocator object.
- Something along the lines:
-
- class PersonMapper {
- PersonAllSet* s;
- Person* p;
- public:
- PersonMapper(PersonAllSet* a_s, Person* a_p) : s(a_s), p(a_p)
- { s->Get(p); }
- ~PersonMapper()
- { s->UnGet(p); }
- };
-
- Then the loop may look like:
-
- while (allPersons->Seek (1, PtCURRENT) == 0)
- {
- PersonMapper pmap(allPersons, thisPerson);
- thisPerson->DoSomething();
- }
-
- Comments?
-
- Niklas
- --
- Niklas Hallqvist Phone: +46-(0)31-40 75 00
- Applitron Datasystem Fax: +46-(0)31-83 39 50
- Molndalsvagen 95 Email: niklas@appli.se
- S-412 63 GOTEBORG, Sweden mcsun!seunet!appli!niklas
-