Detailed Description
The QSharedDataPointer class provides a pointer to a shared data object.
QSharedDataPointer<T> makes it easier to write your own implicitly shared classes. It handles reference counting behind the scenes in a thread-safe manner, ensuring that classes that use it can be reentrant.
Implicit sharing is used throughout Qt to combine the memory and speed efficiency of pointers with the ease of use of value types. See the Shared Classes page for more information.
Let's suppose that you want to make an Employee class implicitly shared. The procedure is:
- Define the Employee class with a single data member variable of type QSharedDataPointer<EmployeeData>.
- Define an EmployeeData class that derives from QSharedData and that contains all the variables that you would normally put in Employee.
To show how this works in practice, we will review the entire source code for an implicitly shared Employee class. Here's the header file that defines the Employee class:
#ifndef EMPLOYEE_H
#define EMPLOYEE_H
#include <QSharedData>
#include <QString>
class EmployeeData : public QSharedData
{
public:
int id;
QString name;
};
class Employee
{
public:
Employee();
Employee(int id, const QString &name);
void setId(int id) { d->id = id; }
void setName(const QString &name) { d->name = name; }
int id() const { return d->id; }
QString name() const { return d->name; }
private:
QSharedDataPointer<EmployeeData> d;
};
#endif
All accesses to the data in the setter and getter functions are made through the QSharedDataPointer object d. For non-const functions, operator->() automatically calls detach(), ensuring that modifications to one Employee object don't affect other Employee objects.
In this example, the EmployeeData type is a simple class with a default constructor and a copy constructor provided by C++. If member-per-member copy isn't sufficient for your own data type, you must implement your own copy constructor.
Let's now see how to implement the Employee constructors:
Employee::Employee()
{
d = new EmployeeData;
d->id = 0;
}
In the default constructor, we create an object of type EmployeeData and assign it to the d pointer using operator=().
Employee::Employee(int id, const QString &name)
{
d = new EmployeeData;
d->id = id;
d->name = name;
}
In the constructor that takes an ID and an employee's name, we also create an object of type EmployeeData and assign it to the d pointer.
In this example, we don't need to provide a copy constructor, an assignment operator, or a destructor for Employee. The default implementations provided by C++, which invoke QSharedDataPointer's copy constructor, assignment operator, or destructor, are sufficient. And this is true in general, i.e. for any QSharedData subclass which only stores values (or implicitly shared classes), such as int, double, QString, QStringList, QList<QWidget*>, and so on.
Behind the scenes, QSharedDataPointer automatically increments or decrements the reference count of the shared data object pointed to by d, and deletes shared objects when the reference count reaches 0.
See also QSharedData.
Member Function Documentation
QSharedDataPointer::QSharedDataPointer ()
Constructs a QSharedDataPointer initialized with a null pointer.
QSharedDataPointer::QSharedDataPointer ( T * sharedData )
Constructs a QSharedDataPointer that points to sharedData.
This function automatically increments sharedData's reference count.
QSharedDataPointer::QSharedDataPointer ( const QSharedDataPointer & other )
Constructs a copy of other.
This function automatically increments the reference count of the shared data object pointed to by other.
QSharedDataPointer::~QSharedDataPointer ()
Destroys the QSharedDataPointer.
This function automatically decrements the reference count of the shared object and deletes the object if the reference count reaches 0.
const T * QSharedDataPointer::constData () const
Returns a const pointer to the shared object.
This function does not call detach().
See also data().
T * QSharedDataPointer::data ()
Returns a pointer to the shared object.
This function does a detach().
See also constData().
const T * QSharedDataPointer::data () const
This is an overloaded member function, provided for convenience. It behaves essentially like the above function.
This function does not call detach().
void QSharedDataPointer::detach ()
If the shared data's reference count is greater than 1, creates a deep copy of the shared data.
This function is automatically called by QSharedDataPointer when necessary. You should never need to call it yourself.
QSharedDataPointer::operator T * ()
Returns a pointer to the shared object.
This function does a detach().
See also data() and constData().
QSharedDataPointer::operator const T * () const
Returns a pointer to the shared object.
This function does not call detach().
bool QSharedDataPointer::operator! () const
Returns true if this pointer is null; otherwise returns false.
bool QSharedDataPointer::operator!= ( const QSharedDataPointer<T> & other ) const
Returns a true if the pointer to the shared object in other is not equal to to the pointer to the shared data in this else returns false.
This function does not call detach().
T & QSharedDataPointer::operator* ()
Provides access to the shared object's members.
This function does a detach().
const T & QSharedDataPointer::operator* () const
This is an overloaded member function, provided for convenience. It behaves essentially like the above function.
This function does not call detach().
T * QSharedDataPointer::operator-> ()
Provides access to the shared object's members.
This function does a detach().
const T * QSharedDataPointer::operator-> () const
This is an overloaded member function, provided for convenience. It behaves essentially like the above function.
This function does not call detach().
QSharedDataPointer & QSharedDataPointer::operator= ( const QSharedDataPointer & other )
Assigns other to this pointer.
This function automatically increments the reference count of the shared data object pointed to by other, and decrements the reference count of the object previously pointed to by this QSharedDataPointer. If the reference count reaches 0, the shared data object is deleted.
QSharedDataPointer & QSharedDataPointer::operator= ( T * sharedData )
This is an overloaded member function, provided for convenience. It behaves essentially like the above function.
Sets this QSharedDataPointer to point to sharedData.
This function automatically increments sharedData's reference count, and decrements the reference count of the object previously pointed to by this QSharedDataPointer. If the reference count reaches 0, the shared data object is deleted.
bool QSharedDataPointer::operator== ( const QSharedDataPointer<T> & other ) const
Returns a true if the pointer to the shared object in other is equal to to the pointer to the shared data in this else returns false.
This function does not call detach().