Getting Started Documentation Glish Learn More Programming Contact Us
Version 1.9 Build 1556
News FAQ
Search Home


next up previous contents index
Next: The Design of AIPS++ Up: Documentation Previous: Document Type Definition

Example Header File

\#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 up previous contents index
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