[Development] Don't use Private *d when your class is immutable

Marc Mutz marc.mutz at kdab.com
Fri Mar 3 12:19:42 CET 2017


On Friday 03 March 2017 10:59:21 Lars Knoll wrote:
> I agree, that we should not use any implicit sharing in those cases. But in
> many cases, I don’t see a problem using a pointer to the data. Of course
> if shouldn’t detach. Instead, it should be explicitly shared (with or
> without refcounting depending on whether the data is generated at compile
> or runtime). Using an integer and a global lookup table would lead to more
> complex code in that case.

If you have a pointer to static-storage duration data, by all means use that 
instead of an int, sure. But you're locking yourself into a particular 
implementation that way, incl. not being able to use a dynamic array because 
addresses would change on reallocation. Int indexes are stable.

But don't - ever- use ref-counting on immutable classes. It's not easier (you 
need to implement all the special member functions, which peoole, me 
included[1][2], get wrong more often than we dare to admit). 

People just *think* ref-counting is easier, because they're used to it and you 
can just take a similar Qt class, and copy the implementation and it's just 
harder to copy one with an int index, for lack of widespread use.

That doesn't make it good. QFileSelector being a QObject is similar: People 
are used to inherit from QObject for signals and properties, so they do it 
every time. That's ok. Unless review doesn't catch it and it gets merged.

The simplest implementation of an immutable class that cannot or should not 
contain all state inline (like QRect) is an int + Q_GLOBAL_STATIC(Container). 
If you put all init code into the ctor of the Container class, then you get 
thread-saftey for free, too. Only if you want to add entries dynamically you 
need to think about threading. And all the special member functions come for 
free, too, fully optimal (nothrow, inline).

People have no problem implementing the business logic (property getters and 
setters). There're tests for that. They have problems with the boilerplate 
code, like remembering to add the move assignment operator, making it nothrow 
(who cares? we compile without exceptions!), the move ctor cannot be inline, 
they bikeshed over formatting and whether move-assignment uses just swap or 
move-and-swap... endless potential for problems.

Only by ignoring these problems can one think about ref-counting as being 
easier.

It's not.

Thanks,
Marc

[1] https://codereview.qt-project.org/148558
[2] https://codereview.qt-
project.org/#/c/167229/3/src/network/ssl/qssldiffiehellmanparameters.cpp,unified

-- 
Marc Mutz <marc.mutz at kdab.com> | Senior Software Engineer
KDAB (Deutschland) GmbH & Co.KG, a KDAB Group Company
Tel: +49-30-521325470
KDAB - The Qt, C++ and OpenGL Experts



More information about the Development mailing list