11.5.  Flyweight Pattern: Implicitly Shared Classes

[ fromfile: refcount.xml id: refcount ]

To make your own implicitly shared flyweight, you can write your own reference counting code, or reuse two Qt classes: QSharedData and QSharedDataPointer.

Figure 11.4.  Example QSharedData Private Implementation

Example QSharedData Private Implementation

Example 11.15. src/mystring/shareddata/mystring.h

#ifndef MYSTRING_H
#define MYSTRING_H
#include <iostream>
class MyString {
public:
    MyString(const MyString& str); 
    MyString& operator=(const MyString& a);
    MyString(); 
    MyString(const char* chptr);  
    explicit MyString(int size);
    virtual ~MyString();
    friend std::ostream& operator<<(std::ostream& os, const MyString& s);
    int length() const;
    MyString& operator+= (const MyString& other);
    friend MyString operator+(const MyString&, const MyString&);
protected:
    int   m_Len;
    char* m_Buffer;    1
    void  copy(const char* chptr);
};
#endif        //  #ifndef MYSTRING_H

1

Pointer to the start of dynamic array


Example 11.16. src/mystring/shareddata/stringdata.h

[ . . . . ]
class StringData : public QSharedData, public MyString {
public:
    friend class SString;
    StringData() {}
    StringData(const char* d) : MyString(d) {}
    explicit StringData(int len) : MyString(len) {}
    StringData(const StringData& other) 
             : QSharedData(other), MyString(other) {}    
};
[ . . . . ]

Example 11.17. src/mystring/shareddata/sstring.h

[ . . . . ]
class SString {
public:
    SString();
    explicit SString(int len);
    SString(const char* ptr);
    SString& operator+= (const SString& other);
    int length() const;
    int refcount() const {return m_d->ref;}
    friend SString operator+(SString, SString);
    friend std::ostream& operator<< (std::ostream&, const SString&);
[ . . . . ]
private:
    // Private Implementation Pattern
    QSharedDataPointer<StringData> m_d;
    
};
[ . . . . ]

Example 11.18. src/mystring/shareddata/sharedmain.cpp

#include <iostream>
#include "sstring.h"
using namespace std;

void passByValue(SString v) {
    cout << v << v.refcount() << endl; 1
    v = "somethingelse";
    cout << v << v.refcount() << endl; 2
}

int main (int argc, char* argv[]) {
    SString s = "Hello";
    passByValue(s);
    cout << s << s.refcount() << endl; 3
}

1

refcount=2

2

refcount=1

3

refcount=1