---
name: "refcount"
section: "3bobcat"
platform: "linux"
package: "libbobcat-dev"
version: "2.08.01-1"
release: "Debian 6.0 (Squeeze)"
platforms: ["linux"]
url: "https://new.carta.tech/refcount"
---

# refcount(3bobcat)

Base class implementing reference counting.

## NAME

FBB::RefCount - Base class implementing reference counting.

## SYNOPSIS

**#include \<bobcat/refcount\>**\
 Linking option: *-lbobcat*

## DESCRIPTION

**RefCount** implements a virtual base class implementing reference counting. When reference counting is used, objects share the memory of a (usually big or complex) data structure, until objects need to modify their data, in which case they obtain a copy of the data of their own. This approach is most useful with classes that seldomly alter their data, but consult their data most of the time.

As an example, consider hidden structures as found in the [**regcomp**(3)](/regcomp/3.md) function: there is no documented way to copy an existing compiled regular expression, so if multiple objects must refer to the same regular expression, the expression should be compiled once. Thereafter, a reference count monitors the number of objects using the compiled expression. Only when the last object is destroyed the compiled expression is freed.

In general, objects using reference counting should obtain their own data if they need to alter their data. This situation is also called \`copy-on-write’. Copy-on-write is implemented by obtaining a copy of the data before any modification of the data takes place. So, each non-const member function should first copy the data, and should only then modify its own data. Constant members may simply refer to the data, without the need to copy them first.

The class **RefCount** should be embedded in programs as follows:

- o

  **RefCount** defines a *virtual base class*, defining all members that are required to implement reference counting. The class is a virtual base class since it defines a member **virtual RefCount \*clone() const = 0**, which must return a real copy of the derived class object (cf. Gamma et al.’s (1995) *proxy* Design Pattern).

- o

  From **RefCount** a class (named **Data** in this man page) is derived defining the functionality that is required to manipulate the data: this class may contain constructors, overloaded operators, accessors, modifiers, etc.

- o

  A third class (called **Client** in this man page) defines the actual interface to the program in which reference counting is required. In its purest form, **Client** only has a **Data \*** data member referring to the (possibly shared) data. The functionality offered to the users of **Client** objects is normally defined by shadowing the functionality defined by **Data**, using simple one-line in-line functions.

Except for **clone()**, there are several issues to bear in mind when using reference counting as defined by **RefCount**:

- o

  When **Client** share data (e.g., when using a copy constructor or an overloaded assignment operator), **RefCount::share()** should be called rather than **operator new**. Since at this point the data are shared with other objects, no copy is required, and the use of **operator new** should be avoided.

- o

  When **Client** objects go out of scope, the destructor should call **RefCount::release()** rather than **operator delete** to disassociate itself from the object’s data. The **operator delete** should not be called directly, since this might prematurely destroy data shared with other objects.

- o

  All members modifying data (i.e., all non-const member functions) should call **RefCount::modifying()** prior to performing the modification. This ensures that the object operates on its own data, rather than modifying shared data. Except for the abovementioned items, all members of **Client** should be implemented as usual: constructors use **new Data(argument list)**, **clone()** returns a pointer to a clone of itself, etc.. Refer to the code  example for an actual implementation.

## NAMESPACE

**FBB**\
 All constructors, members, operators and manipulators, mentioned in this man-page, are defined in the namespace **FBB**.

## INHERITS FROM

\-

## PROTECTED CONSTRUCTORS

- o

  **RefCount()**:\
   This constructor implements the default constructor.

- o

  **RefCount(RefCount const &other)**:\
   This constructor implements the copy constructor, which is a convenience function for **Data**’s copy constructor, but otherwise acting identically as **RefCount()** itself.

## PROTECTED DESTRUCTOR

- o

  **virtual ~RefCount()**:\
   The destructor is an empty virtual member, thus allowing **RefCount \*** variables to destroy any derived class objects they point to.

## PUBLIC MEMBER FUNCTIONS

- o

  **size\_t refcount() const**:\
   This member returns the current number of objects sharing the data.

- o

  **void release()**:\
   This member must be called by **Client** objects that must disassociate themselves from the (possibly shared) data. In practice it is called by the **Client**’s destructor and overloaded assignment operator. It will actually call **Data**’s destructor when the object was the only object still referring to the data.

## PUBLIC STATIC MEMBER FUNCTIONS

- o

  **Data \*RefCount::share(Data const \*ptr)**:\
   This member should be called by the constructor of **Client** objects sharing another client’s data. In practice it is called by the client’s copy constructor and overloaded assignment operator. It receives the actual pointer to the data as its argument, and returns the new value of the pointer.

-

  Note that **Data** is not a hard-coded class: the function is implemented as a template member, and so it can be used by every class derived from **RefCount**.

-

  - o

  **Data &RefCount::modifying(Data \*\*ptr)**:\
   This member should be called by **Client** objects’ non-const members, just before modifying data. The function may alter the value of the client’s **Data \*** data member. It returns a *reference* to the data, allowing the client’s member function to call the required **Data** modifier in one single statement, using the member selection operator (dot).

-

  Note that **Data** is not a hard-coded class: the function is implemented as a template member, and so it can be used by every class derived from **RefCount**.

-

  This function performs a **dynamic\_cast**, which will always succeed if **Data** was indeed derived from **RefCount**. A **bad\_cast** is thrown if the cast fails.

## EXAMPLE

The following example illustrates the use the class **RefCount**. A class **Data** is derived from **RefCount**, defining **clone()**, several standard members (copy constructor, overloaded assignment operator) as *private* members, and a default constructor, destructor, accessor and modifier member as public members.

The class that is used directly by the program is **Client**, given next. It defines all standard constructors and members, and it shadows the accessor and modifier members of **Data**:

Finally, a small program using **Client** is shown.

```
/*
                              driver.cc
*/
#include <iostream>
#include <string>
#include <sstream>
#include "../refcount"
using namespace std;
using namespace FBB;
// The class Data uses reference counting. Data are shared until they are
// modified.
class Data: public RefCount
{
    static size_t s_n;        // count the number of objects in use
    public:
        Data()                  // all other constructors are built like this:
        {                       // using RefCount’s default constructor.
            s_n++;
            cout << "Data(), " << s_n << " Data objects created\n";
        }
        virtual ~Data()
        {
            s_n--;
            cout << "~Data(), " << s_n << " Data objects left\n";
        }
        string accessor() const
        {
            ostringstream ostr;
            ostr << "calling Data::accessor(). Data at " << this;
            return ostr.str();
        }
        void modifier()             // a plain modifier
        {
            cout << "calling Data::modifier(). Data at " << this << endl;
        }
                                    // support function for operator>>()
        istream &extract(istream &istr)
        {
            cout << "extraction from istream. " <<
                                    "Enter a non-empty line of text" << endl;
            string s;
            getline(istr, s);
            cout << "Read: " << s << endl;
            return istr;
        }
                                    // another modifier: operator+=()
        Data &operator+=(Data const &rvalue)
        {
            cout << "calling Data::operator+=(): @`" <<
                    this << "’ += @`" << &rvalue << "’\n";
            return *this;
        }
    private:
        Data &operator=(Data const &other);   // NI
        Data(Data const &other) // The copy constructor MUST call RefCount’s
        :                       // CC. Data(Data) is a convenience function
                                // for clone() and should not be available to
            RefCount(other)     // clients, thus enforcing the use of
        {                           // clone() / share() / release()
            s_n++;
            cout << "Data(Data const &), " << s_n << " Data objects created\n";
        }
        virtual RefCount *clone() const
        {
            cout << "Data::clone()\n";
            return new Data(*this);
        }
};
// Client: uses a pointer to a Data object. It is implemented in an
// almost standard way. Deviations are:
//  *. Copy():       should call share() rather than new Data(*d_dataPtr)
//  *. Destroy():    should call release() rather than delete d_dataPtr;
//  *. non-const members modifying d_dataPtr’s data"
//                   should call Data:modifying() first.
class Client
{
                                                     // modifying friend
                                                     // see below at modifier()
    friend istream &operator>>(istream &istr, Client &c)
    {
        return Data::modifying(&c.d_dataPtr).extract(istr);
    }
    Data *d_dataPtr;
    public:
            // Constructors, destructor, overloaded assignment operator: all
            // follow my standard copy() / destroy() approach.
        Client()                    // new object, creates its own data
        :                           // use new Data(...) to initialize.
            d_dataPtr(new Data())
        {}
        ~Client()
        {
            destroy();
        }
        Client(Client const &other)
        {
            copy(other);
        }
        Client &operator=(Client const &other)
        {
            if (this != &other)
            {
                destroy();
                copy(other);
            }
            return *this;
        }
        string accessor() const         // accessors shadow Data’s members
        {
            return d_dataPtr->accessor();
        }
                                        // modifiers call modifying first
        void modifier()                 // simple modifier
        {
            Data::modifying(&d_dataPtr).modifier();
        }
                                        // arithmetic assignment modifier
        Client &operator+=(Client const &other)
        {
            Data::modifying(&d_dataPtr).operator+=(*other.d_dataPtr);
            return *this;
        }
    private:
        void copy(Client const &other)  // copying is sharing: call share()
        {
            d_dataPtr = Data::share(other.d_dataPtr);
        }
        void destroy()                  // destroying is disassociation: call
        {                               // release
            d_dataPtr->release();
        }
};
size_t Data::s_n = 0;
Client const operator+(Client const &lvalue, Client const &rvalue)
{
    return Client(lvalue) += rvalue;
}
int main()
{
    cout << "Construction:\n";
    Client c;
    cout << "Extraction c from cin:\n";
    cin >> c;
    cout << "c’s Modifier called:\n";
    c.modifier();
    cout << "operator += :\n";
    c += c;
    cout << "operator + :\n";
    c + c;
    cout << "Copy construction:\n";
    Client c2(c);
    cout << "Assignment:\n";
    c = c2;
    cout << "Accessors:\n";
    cout << "access c:  " << c.accessor() << endl;
    cout << "access c2: " << c2.accessor() << endl;
    cout << "operator += :\n";
    c += c;
    cout << "c’s Modifier called:\n";
    c.modifier();
    cout << "Accessors:\n";
    cout << "access c:  " << c.accessor() << endl;
    cout << "access c2: " << c2.accessor() << endl;
    cout << "c2’s Modifier called:\n";
    c2.modifier();
    cout << "resetting refcount to 2:\n";
    c = c2;
    cout << "Extraction c from cin:\n";
    cin >> c;
    cout << "End of program:\n";
}
```

## FILES

*bobcat/refcount* - defines the class interface

## SEE ALSO

[**bobcat**(7)](/bobcat/7.md)

## BUGS

None Reported.

## DISTRIBUTION FILES

- o

  *bobcat\_2.08.01-x.dsc*: detached signature;

- o

  *bobcat\_2.08.01-x.tar.gz*: source archive;

- o

  *bobcat\_2.08.01-x\_i386.changes*: change log;

- o

  *libbobcat1\_2.08.01-x\_\*.deb*: debian package holding the libraries;

- o

  *libbobcat1-dev\_2.08.01-x\_\*.deb*: debian package holding the libraries, headers and manual pages;

- o

  *http://sourceforge.net/projects/bobcat*: public archive location;

## BOBCAT

Bobcat is an acronym of \`Brokken’s Own Base Classes And Templates’.

## COPYRIGHT

This is free software, distributed under the terms of the  GNU General Public License (GPL).

## AUTHOR

Frank B. Brokken (**f.b.brokken@rug.nl**).
