c++reference-counting

Reference Counting Using RCObjects vs. static inline C++


I am currently reading More Effective C++ (1995) by Scott Meyers.

In Item 29 - Reference Counting, the author metioned that the primary benefits of using reference counting are

The book suggests that we use RCObjects to accomplish this goal. For example:

class String
{
    public:
        String(const char* value = "");
        String& operator=(const String& rhs);

        ~String();

    private:
        // Holds a reference count and a string value
        struct StringValue
        {
            size_t refCount;
            bool shareable;
            char* data;

            StringValue(const char *initValue);
            ~StringValue();
        };

        // Value of this String
        StringValue* value;
};

However, the first book I used to learn C++ (Beginning C++20, 6th Edition, Ivor Horton) mentioned that from C++17, we can use "static inline" variable to accomplish reference counting as well. For example:

class Test
{
    public:
        Test(int number)
            : m_number { number}
        {
            ++m_count;
        }
        
        ~Test()
        {
            --m_count;
        }
        
        static std::size_t getCount()
        {
            return m_count;
        }
        
    private:
        int m_number;
        static inline std::size_t m_count = 0;
};


int main()
{
    Test t1 { 1 };
    Test t2 { 1 };
    Test t3 { 1 };
    Test t4 { 1 };
    
    std::cout << Test::getCount();    // 4
}

I am wondering whether I should use the method provided in More Effective C++ or Beginning C++20? Or they actually accomplish different things?


Solution

  • You are comparing two totally different things!

    The string example is about reusing the data of a string, maybe by copying the string later and wait for own data copy until the data should be modified ( copy on write ) or any other algorithms. It is as such an implementation of shared data. The reference counter counts the number of "users" of these data and not of all objects.

    The second one is really about object counting which really gives you the number of all objects living during execution.