Home > Net >  Pointer to const object as a data member
Pointer to const object as a data member

Time:05-06

Accordingly to C best practices on IsoCpp we shouldn't have a const or reference data member: C.12: Don’t make data members const or references

But it does not specify if a pointer to a const object is allowed or not. Consider the example:

class Connection {
    gsl::not_null<const Network*> m_network;
    ...

public:
    [[nodiscard]] const Network* getNetwork() const;
    ...
}

// Implementation
const Network* Connection::getNetwork() const {
    return m_network;
}

Is it still conformant with the best practice described? The pointer isn't const but the data the pointer points to is.

Should we remove const from member declaration but still mark the getter return type as a pointer to const?

CodePudding user response:

Yes, you can

If you have a const data member, the copy and move constructor are deleted. But this only applies if the pointer itself is const, not the pointed value.

const & or const * are only fine when the class is uncopyable (like a "manager class" of some sort)

CodePudding user response:

It depends.

The reason this recommendation exists, is to make your type copyable and assignable, with both having matching semantics.

So consider this:

struct Connection {
  Network const& network;
  /**/
};

Copying this is perfectly fine, right? But then assigning breaks because network will not be reseatable.

So in this case, replacing that member with an e.g. std::shared_ptr<Network const> is fine. Presumably several connections can use the same network.

But -- if you do not want sharing but each object to have its own copy of the member, then you are left with reconstructing that member on assignment, because the old object cannot be changed. Depending on the object that might not be what you want to do.

For example:

struct Connection {
  std::shared_ptr<Network const> network;
  std::unique_ptr<std::vector<Entry> const> properties;
};

Aside from a pointer-to-vector being bad form (double indirection for no good reason). Reconstructing a vector anew requires a new memory allocation, while just reusing the old will not (assuming there was enough memory allocated).

Granted, this is a bit of constructed example, and there would maybe be a way to go around that. But the point is, that the similarty of your copy and assignment will heavily depend on the quality of the copy and assignment of the member object.

In such a case the same reasoning that applied to the situation without the pointer similarly applies to the situation with the pointer. You will have to decide whether that is acceptable for your type.


However, I hold that not every type must be assignable. You can make the conscious decision to have a type that just cannot be assigned to. Then and only then, just have a const member without any indirection.

  • Related