0

a simple piece of code:

class HasPtr
{
public:
    HasPtr(const string& s = string()) :ps(new string(s)), i(0), use(new size_t(1)) {}
    HasPtr(const HasPtr& p) :ps(p.ps), i(p.i), use(p.use) { ++* use; }
    HasPtr& operator=(const HasPtr&);
    ~HasPtr();
private:
    string* ps;
    int i;
    size_t* use;
};

HasPtr& HasPtr::operator=(const HasPtr& rhs)
{
    ++* rhs.use;
    if (-- * use == 0) {
        delete ps;
        delete use;
    }
    ps = rhs.ps;
    i = rhs.i;
    use = rhs.use;
    return *this;
}

The parameter of the copy assignment operator is const.c++ primer says A const type can use most but not all of the same operations as its nonconst version.The one restriction is that we may use only those operations that cannot an object. Why can the value pointed to by use(++* rhs.use) be modified here? Does this violate the rules for const properties?

gaofeng
  • 393
  • 1
  • 3
  • 11
  • 5
    `++* rhs.use;` don't write code like this. – Jason Apr 03 '23 at 14:03
  • 1
    You're missing `if (this != &rhs)` – metablaster Apr 03 '23 at 14:06
  • The operator may handle self-assignment. – gaofeng Apr 03 '23 at 14:07
  • 1
    If `ps` is a `const` pointer you cannot change `ps`. But there's nothing that prevents you from changing whatever `ps` points to. A pointer, and the object the pointer is pointing to, are two completely independent things. Either one can be `const`, on its own merits. – Sam Varshavchik Apr 03 '23 at 14:07
  • `p.use` is `const` and you can't change it, the value it points to isn't `const` so can be changed – Alan Birtles Apr 03 '23 at 14:08
  • Here, `use` is not modifed, so the technically there is no violation of the const correctness. If fact, it depends on does `*use` correspond to a designated item, or an included item. – dalfaB Apr 03 '23 at 14:09
  • And in the second case, it is clearly a problem, but may can caracterise the pointer see https://stackoverflow.com/questions/4729820/propagate-constness-to-data-pointed-by-member-variables – dalfaB Apr 03 '23 at 14:19

2 Answers2

2

The members of const class are const. The const version of size_t* is

size_t* const use;

Which is a constant pointer of size_t to non-constant object use. You cannot change what the pointer points to, but when you dereference the pointer you get non-const object, which you can modify.

Karen Baghdasaryan
  • 2,407
  • 6
  • 24
1

why can the value pointed to by use(++* rhs.use) be modified?

use is a pointer to non-const, so it is well-formed to modify through it. In this case, it points to a non-const dynamic object, so modifying the pointed object is well-defined.

Does this violate the rules for const properties?

No.

eerorika
  • 232,697
  • 12
  • 197
  • 326