| Version 1.9 Build 1556
|
|
Next: The Design of AIPS++
Up: Documentation
Previous: Document Type Definition
\#if !defined(AIPS\_COUNTEDPTR\_H)
\#define AIPS\_COUNTEDPTR\_H
//\# Copyright (C) 1992,1996
//\# Associated Universities, Inc. Washington DC, USA.
//\#
//\# This program is free software; you can redistribute it and/or modify
//\# it under the terms of the GNU General Public License as published by
//\# the Free Software Foundation; either version 2 of the License, or
//\# (at your option) any later version.
//\#
//\# This program is distributed in the hope that it will be useful,
//\# but WITHOUT ANY WARRANTY; without even the implied warranty of
//\# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//\# GNU General Public License for more details.
//\#
//\# You should have received a copy of the GNU General Public License
//\# along with this program; if not, write to the Free Software
//\# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//\#
//\# The AIPS++ consortium may be reached by email at aips2-request@nrao.edu.
//\# The postal address is: AIPS++ Consortium, c/o NRAO, 520 Edgemont Rd.,
//\# Charlottesville, Va. 22903-2475 USA.
template<class t> class CountedPtr;
template<class t> class CountedConstPtr;
//
// This is a dummy class which is not part of "aips/CountedPtr.h". I've
// included it for the purpose of demonstration. The things to note in
// the comments in general
// are:
// <list>
// <item> The opening blank comment line is significant. It is the
// marker for the first paragraph.
// <item> Blank lines between paragraphs are significant. They
// separate paragraphs.
// <item> The blank comment line at the end of the comment is
// significant. It closes the last paragraph.
// </list>
//
// In addition, although typically the divisions, "div", are not
// specified for a comment they are generated before and after the comment.
//
template<class t> class generic\_useless\_template \{
private:
t *val;
public:
//
// Generic ctor comment.
//
generic\_useless\_template(t *nv) : val(nv) \{\}
//
// This is one of the indirection operators. It is here to demonstrate
// the use of the "+grp" extractor command.
//+grp
t \&operator*() \{ return *val;\}
t *operator->() \{return val;\}
//-grp
//
// Just another function.
//
void set(t *n) \{
if (val) delete val;
val = n;
\}
//
// Generic dtor comment.
//
~generic\_useless\_template() \{ delete val;\}
\};
//
// <category lib=aips sect=memory>
//
// This class stores the reference count and the pointer to the
// "real data".
//
// It is currently a template and is used such that
// "t" is the "true" type of the stored pointer. This means, however,
// that when it is used a template instantiation must be done for
// each type which "t" assumes. This makes debugging easier, but
// in the future all of these pointers could be declared with void
// type to avoid template instantiations.
//
template<class t> class PtrRep \{
friend class CountedPtr<t>;
friend class CountedConstPtr<t>;
private:
t *val;
unsigned int count;
protected:
//
// This constructor sets up the reference count to "1" and
// initializes the pointer to the "real" data.
//
PtrRep(t *v) : val(v), count(1) \{\}
//
// <warn>
// This destructor, if called, deletes the "true" data.
//
~PtrRep() \{delete val;\}
\};
//
// <category lib=aips sect=memory>
//
// This class maintains a count of pointers which point to particular
// data, and it deletes the data only when no other counted pointers
// are pointing at it.
//
// This class is used as a pointer to constant data. As such, it
// only has the subset of the "CountedPtr" functions which are relevant
// for constant data.
//
template<class t> class CountedConstPtr \{
protected:
PtrRep<t> *ref;
public:
//
// After the counted pointer is initialized the value should no
// longer be manipulated by the raw pointer of type "t*".
//
CountedConstPtr(t *val) : ref(new PtrRep<t>(val)) \{\}
//
// After the counted pointer is initialized the value should no
// longer be manipulated by the raw pointer of type "t*".
//
CountedConstPtr(const CountedConstPtr<t> \&val) : ref(val.ref) \{
if (ref)
(*ref).count++;
\}
//
// The destructor deletes the data only when there are no other
// counted pointers pointing at it.
//
~CountedConstPtr() \{
if (ref) \{
(*ref).count--;
if ((*ref).count == 0)
delete ref;
\}
\}
//
// The CountedConstPtr indirection operator simply returns a
// reference to the value being protected.
//
// <note> The address of the reference returned should not be
// stored for later use.
//
const t \&operator*() const \{
return(*(*ref).val);
\}
//
// This dereferencing operator behaves as expected; it returns the
// pointer to the value being protected, and then its dereferencing
// operator will be invoked as appropriate.
//
const t *operator->() const \{
return ((*ref).val);
\}
\};
//
// <category lib=aips sect=memory>
//
// This class maintains a count of pointers which point to particular
// data, and it deletes the data only when no other counted pointers
// are pointing at it.
//
// This class is used as a pointer to non-constant data, and it has
// all of the possible manipulation functions.
//
// <note> It is possible that use the <code>replace</code> function
// can change the data to which a <code>CountedConstPtr</code> points.
//
template<class t> class CountedPtr : public CountedConstPtr<t> \{
public:
//
// Simple function which leaves the work to the parent constructor.
//
CountedPtr(t *val) : CountedConstPtr<t>(val) \{\}
//
// Simple function which leaves the work to the parent constructor.
//
CountedPtr(const CountedPtr<t> \&val) : CountedConstPtr<t>(val) \{\}
//
// This assignment operator allows CountedPtrs to be freely assigned to
// each other.
//
CountedPtr<t> \&operator=(CountedPtr<t> \&val) \{
if (ref) \{
(*ref).count--;
if ((*ref).count == 0)
delete ref;
\}
ref = val.ref;
if (ref)
(*ref).count++;
return *this;
\}
//
// This function changes the value for this CountedPtr and all of
// the other CountedPtrs which pointed to this same value.
//
// <note> This can change the value to which a CountedConstPtr points.
//
void replace(t *v) \{
if (ref) \{
if ((*ref).val)
delete (*ref).val;
(*ref).val = v;
\}
\}
//
// This assignment operator allows the object to which the current
// CountedPtr points to be changes.
//
CountedPtr<t> \&operator=(t *v) \{
if (ref) \{
(*ref).count--;
if ((*ref).count == 0)
delete ref;
\}
ref = new PtrRep<t>(v);
return *this;
\}
//
// The CountedConstPtr indirection operator simply returns a
// reference to the value being protected.
//
// <note> The address of the reference returned should not be
// stored for later use.
//
t \&operator*() \{
return(*(*ref).val);
\}
//
// This dereferencing operator behaves as expected; it returns the
// pointer to the value being protected, and then its dereferencing
// operator will be invoked as appropriate.
//
t *operator->() \{
return ((*ref).val);
\}
\};
\#endif
Next: The Design of AIPS++
Up: Documentation
Previous: Document Type Definition
  Contents
  Index
Please send questions or comments about AIPS++ to aips2-request@nrao.edu.
Copyright © 1995-2000 Associated Universities Inc.,
Washington, D.C.
Return to AIPS++ Home Page
2006-10-15