home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!usc!news
- From: coller@alnitak.usc.edu (Lee D. Coller)
- Newsgroups: comp.lang.c++
- Subject: Avoiding returning references to Temporaries
- Date: 6 Sep 1992 12:02:21 -0700
- Organization: University of Southern California, Los Angeles, CA
- Lines: 81
- Sender: coller@alnitak.usc.edu (Lee D. Coller)
- Distribution: world
- Message-ID: <lakldtINN17n@alnitak.usc.edu>
- NNTP-Posting-Host: alnitak.usc.edu
-
- The following classes represent I problem I have encountered.
-
- class A {
- public:
- void func() = 0;
- };
-
- class B : public A {
- private:
- int _i;
- public:
- void func();
- };
-
- class C: public B {
- private:
- double _d;
- public:
- void func();
- };
-
- class D {
- private:
- /* some information from which to construct a B or C */
- public:
- A getA() const; // ideally
- };
-
- The idea is that the member function D::getA() would be able to construct a
- B or C and return it to the caller as an A. Because of the semantics, most
- likely D::getA() will have to create a temporary, so just returning a
- reference to some pre-existing B or C will not work.
-
- Of course returning an A won't work because the pertinent information in
- either B or C is lost, and won't even compile because A is abstract.
-
- The simple solution is to allocate the B or C off the heap, with the caller
- of D::getA() responsible for deleting it. I don't like this solution
- because it is inelegant and the subclass of B or C is usually not kept
- around outside the scope of the caller.
-
- The obvious solution is to use a class which can be Garbage Collected, but
- C++ currently has no such thing.
-
- The best solution I could come up with is to create another class to handle
- managing a pointer to A such as the following.
-
- class AHandler {
- private:
- A* _a;
- public:
- AHandler(A* a) { _a = a; a->ref(); } // use reference counting GC
- ~AHandler(A* a) { _a->unref(); }
-
- AHandler operator=(const AHandler &a)
- { a._a->ref(); _a->unref(); _a = a._a; }
-
- A* operator->() const { return _a; }
- operator a&() const { return *_a; }
- a& operator*() const { return *_a; }
- };
-
- Then the member function getA() would return an AHandler, that it created
- using a B or C allocated off the heap. Class A would implement reference
- counting (and probably a copy member that return an A*), and AHandler
- would take care of management of the A*. The operators would allow AHandler
- to be treated like an A* or an A, depending on the context (in the actual
- implementation, A includes some overloaded operators for comparison, thus
- the operator a&() conversion).
-
- My question is, I would like to be able to do this without having A handle
- reference counting. Can anyone think of a good method? Am I overlooking
- some simple, elegant solution? Also, is this what is referred to as a
- "Smart pointer class?"
-
- Thanks,
- --
- -----------------------------------------------------------------
- Lee D. Coller (coller@alnitak.usc.edu) +1 (310) 379-0844
- USC Behavioral Technology Labs, 250 N. Harbor Dr. Ste 309
- Redondo Beach, California, 90277
-