What can a 'const' method change?

后端 未结 5 554
遇见更好的自我
遇见更好的自我 2020-12-05 23:46

C++ methods allow a const qualifier to indicate that the object is not changed by the method. But what does that mean? Eg. if the instance variables are pointer

相关标签:
5条回答
  • 2020-12-05 23:50

    What can a 'const' method change?

    Without explicitly casting away constness, a const method can change:

    • mutable data members, and
    • any data the class has non-const access to, irrespective of whether that data's accessible:
      • via member variables that are pointers or references,
      • via pointers or references passed as function parameters,
      • via pointers or references returned by functions,
      • directly in the namespace or class (for statics) containing it.

    For members of class/struct/union type, it relies on the constness of their member functions to determine which operations should be allowed. (It can also change any non-const local variables and by-value parameters, but I know that's not what you're interested in).

    It can call other const methods which will have these same abilities and restrictions.

    Eg. if the instance variables are pointers, does it mean that the pointers are not changed, or also that the memory to which they point is not changed?

    It means the pointers can't be (easily/accidentally) changed. It does not mean that the pointed-to memory can't be changed.

    What you've stumbled on is the logical incorrectness of a const function changing pointed-to or referenced data conceptually owned by the object. As you've found, the compiler doesn't enforce the const correctness you may want or expect here. That's a bit dangerous, but means constness doesn't need to be explicitly removed for pointers/references to other objects which may be changed as a side-effect of the const function. For example, a logging object. (Typically, such objects are not logically "owned" by the object whose const function is operating on them.) The key point is that the compiler can't reliably distinguish the type of logical ownership an object has over pointed-to data, so it's got to guess one way or the other and allow the programmer to either override, or not be protected by const-ness. C++ forgoes the protection.

    Interesting, I've heard Walter Bright's D language flips this default, making pointed-to data const by default in const functions. That's seems safer to me, though it's hard to imagine how often one would end up needing to explicitly cast away constness to allow wanted side-effects, and whether that would feel satisfyingly precise or annoyingly verbose.

    0 讨论(0)
  • 2020-12-05 23:50

    const basically prevents changing the class instance members' values inside the function. This is useful for more clearer interface, but pose restrictions when using inheritance for example. It's sometimes a little bit deceiving (or a lot actually), as in the example you posted.

    const would be most appropriate for Get functions, where it is obvious that the caller is reading a value and has no intentions of changing the object state. In this case you would want to limit the inherited implementations as well to adhere to constness, to avoid confusion and hidden bugs when using polymorphism.

    For example

    class A{
         int i;
       public:
         virtual int GetI() {return i;};
    }
    
    class B : public A{
       public:
         int GetI() { i = i*2; return i;}; // undesirable
    }
    

    changing A to:

    virtual int GetI() const {return i;};
    

    solves the problem.

    0 讨论(0)
  • 2020-12-05 23:53

    const when applied to a method means:

    This means that the state of the object will not be changed by the method.
    This means any members that are part of the objects state can not be modified, nor can any functions that are not also const be called.

    As this relates to pointers. It means the pointer (if it is part of the state) can not be changed. But the object the pointer points at is part of another object so that means you can call non cost methods on this object (as it is not part of the state of this object).

    0 讨论(0)
  • 2020-12-06 00:08

    There are two aspects to this question:

    1. what does const mean to the compiler?
    2. how does const apply when it cannot be validated by the compiler?

    Question 1

    The first is rather simple. The compiler validates that no data members are modified (unless they are qualified as mutable). It validates this recursively: for any user-defined types, it checks that no non-const methods are invoked. For built-in types, it validates that they are not assigned.

    The transformation for pointers is T* to T*const (const pointer), not const T* (pointer to const). This means that the compiler does not validate that the object pointed to is not modified. Obviously, this leads to question 2.

    Question 2

    How does const apply when not validate by the compiler? It means whatever it should mean to your application. This is usually referred to as logical const. When to use const with respect to logical const-ness is subject to debate.

    0 讨论(0)
  • 2020-12-06 00:12

    Most succinctly, it means that the type of this is const T * inside const member functions, where T is your class, while in unqualified functions it is T *.

    Your method set does not change data, so it can be qualified as const. In other words, myclass::data is accessed as this->data and is of type int * const.

    0 讨论(0)
提交回复
热议问题