2
const std::shared_ptr<int> x (new int (2));
const std::shared_ptr<int> y (x);

copying a shared pointer makes changes to the control block where the 'const' shared pointers point to, does that not contradict the constness part?

mkmostafa
  • 3,071
  • 2
  • 18
  • 47
  • I guess that, in an implementation, either the control block is `mutable`, or perhaps more simply - it's just not an actual member of the `shared_ptr` class; the pointer to it is the member, which doesn't change. – einpoklum Dec 30 '16 at 12:08

3 Answers3

0

shared_ptr contains (generally speaking) two pointers. One to hold an object and second one to 'internal' data with refcount etc. If you make shared_ptr constant it means you cannot modify these pointers, but you can without a problem modify objects they point to.

If this is a contradicion? For me not, but for sure there are people which would say it is. Kind of philosophical question. :)

Michał Walenciak
  • 4,257
  • 4
  • 33
  • 61
-1

The control block is an implementation detail that users do not have access to and should not be concerned with. It is not a part of shared_ptr interface and cannot be observed.

It is the shared_ptr pointer what is const. Which means you cannot reassign it.

It behaves similar to a plain const pointer in this regard: it can be copied, but cannot be reassigned.

Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271
  • "*Which means you cannot reassign it.*" It should mean that you cannot change the members of the object. – Hatted Rooster Dec 30 '16 at 12:11
  • @GillBates You probably confuse `const shared_ptr` with `shared_ptr`. – Maxim Egorushkin Dec 30 '16 at 12:12
  • I kinda agree with Gill, a const object means that its members are not to be changed (unless they are mutable). – mkmostafa Dec 30 '16 at 12:13
  • @mkmostafa What members are you referring to? – Maxim Egorushkin Dec 30 '16 at 12:13
  • Im not taking about the int pointer, im talking about the shared_ptr object, obviously, the control block is a part of the shared pointer and the declaration above indicates that the shared pointer itself is a constant but when its copied, internally something is changed. – mkmostafa Dec 30 '16 at 12:15
  • @MaximEgorushkin [No I'm not](http://stackoverflow.com/a/17793411/1870760). `` makes the pointed to object `const`. `const shared_ptr` should make the members `const`. – Hatted Rooster Dec 30 '16 at 12:15
  • @mkmostafa The control block is an implementation detail, it is not a part of `shared_ptr` interface. The control block and the `shared_ptr` have different lifetimes. – Maxim Egorushkin Dec 30 '16 at 12:16
  • yup i agree with Gill's comment. somehow the shared pointer has a pointer to the control block and it alters the contents of that control block – mkmostafa Dec 30 '16 at 12:16
  • @mkmostafa The fact that you agree with a wrong opinion does not make that opinion right. – Maxim Egorushkin Dec 30 '16 at 12:19
  • @maxim class A { int x; obj* y; }; now imagine that A is instantiated as const object and the pointer y is also created outside A (has a different lifetime) and passed to it. I think u can not still alter the object that y points to through the const instance of A – mkmostafa Dec 30 '16 at 12:20
  • @mkmostafa You may be surprised, but you can alter `obj` through `obj* const y`, this is how `const` works. However, even that is irrelevant here, because the control block is not a part of `shared_ptr` interface. – Maxim Egorushkin Dec 30 '16 at 12:23
  • @maxim Im sorry i was not clear in my comment. I know that u can alter it but is it correct to do so? you are basically saying the whole object is const and yet through pointers u are manipulating a member of that const object – mkmostafa Dec 30 '16 at 12:25
  • @mkmostafa I am risking repeating myself: _The control block is an implementation detail that users do not have access to and should not be concerned with. It is not a part of `shared_ptr` interface and cannot be observed._ – Maxim Egorushkin Dec 30 '16 at 12:25
  • @MaximEgorushkin Doesn't matter, the user is asking how compilers are able to make it work. Implementation detail or not. – Hatted Rooster Dec 30 '16 at 12:27
  • @MaximEgorushkin Does the shared pointer have a member that points to the control block or not? – mkmostafa Dec 30 '16 at 12:28
  • @Mkmostafa Usually yeah, like MSVC. – Hatted Rooster Dec 30 '16 at 12:31
  • @mkmostafa The standard does not require a particular implementation of `shared_ptr`. In fact, you can implement `shared_ptr` with just one pointer to the control block, the direct pointer to the object is an optimization. – Maxim Egorushkin Dec 30 '16 at 12:33
  • @MaximEgorushkin so in your proposal u say that the shared pointer will have 'one pointer to the control block'. My original question is: you don't think -even conceptually- that this is contradicting when the shared pointer is constant that you are altering an object through a member pointer (I know that you can do it). – mkmostafa Dec 30 '16 at 12:36
  • @mkmostafa The only conceptual requirement to `shared_ptr` is that it behaves just like a plain pointer does, but without memory leaks (and with extra `weak_ptr` functionality). – Maxim Egorushkin Dec 30 '16 at 12:38
-1

It can either have the control block member declared as mutable (unlikely, see Maxim's comment), or (more likely) it can have a non-const pointer pointing to the control block as a member. Changing values of the pointed-to control block in a const shared_ptr is allowed, just reassigning that pointer isn't when it's const.

To take a real world example from MSVC2015 (I know I know), shared_ptr has a member _Rep :

private:
    _Ty *_Ptr;
    _Ref_count_base *_Rep;

The shared_ptr can modify the use count through _Rep.

Hatted Rooster
  • 35,759
  • 6
  • 62
  • 122
  • `mutable` is unnecessary here, since `const shared_ptr<>` cannot be assigned to. – Maxim Egorushkin Dec 30 '16 at 12:24
  • @MaximEgorushkin It may have a `mutable` ref count object member that _can_ be changed when `shared_ptr` is `const`. In that case, it's necessary. Even though it's just an implementation detail. – Hatted Rooster Dec 30 '16 at 12:25
  • @DV May I ask why? – Hatted Rooster Dec 30 '16 at 12:28
  • `shared_ptr` cannot possibly have its own ref-count member because the counter is shared between `shared_ptr`s pointing to the same object. – Maxim Egorushkin Dec 30 '16 at 12:28
  • @MaximEgorushkin That wouldn't matter, at the time of ref increasing or decreasing both the `shared_ptrs` are known and thus an implementation can ask for it's ref count / copy it / decrease it. You're right that it's not very sensible but it is possible. – Hatted Rooster Dec 30 '16 at 12:29
  • Such a `shared_ptr` would not work because you would not be able to implement its destructor. The ref-counters would be inconsistent. – Maxim Egorushkin Dec 30 '16 at 12:36