As others have said, a typical example is std::string . In addition to performance issues when locking in multi-threaded programs, there are streaming problems with links to counted lines. Imagine the following:
string s = "hello"; string t = s;
The problem is that non-const operator[] should make a copy of the string if it was split, since the returned link can be used later to change the string (you can assign it without a char link, but operator[] does not know that it must behave differently). On the other hand, const operator[] should avoid creating a copy, as this will eliminate all the advantages of reference counting (this will mean that you always make a copy in practice).
const char &get_first(const string &s) { return s[0]; // no copy, s is const } string s = "hello"; string t = s; // s and t share data const char &c1 = get_first(t); // no copy made here const char &c2 = t[0]; // copy made, since t is non-const // c1 just got invalidated (in fact, it pointing at s[0], not t[0]). s[0] = 'X'; printf("%c, %c\n", c1, c2); // outputs "X, h"
As you can see, this distinction is confusing and can cause really unexpected behavior.
Here is an old article about the semantics of copying to a record and its impact on performance: http://www.gotw.ca/gotw/045.htm .
Here's a suggestion with the motivation to change std::string so that it is not considered a reference in the C ++ 11 standard: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2534. html This is what the above example is based on.
Ds.
source share