Dereferencing a pointer to constant

前端 未结 10 560
深忆病人
深忆病人 2020-12-30 23:09

Let\'s say we have a class called object.

int main(){
    object a;
    const object* b = &a;
    (*b); 
}

Question: b is a pointer to

相关标签:
10条回答
  • 2020-12-30 23:40

    Because that's how the built-in dereference operator * works in C++. If you dereference a pointer of type T *, you get an lvalue of type T. In your case T is const object.

    Neither * operator, not the pointer itself cares (or knows) that the object the pointer is pointing to is actually non-constant. It just can't be any other way within the concept of static typing used by C++ language.

    The whole purpose of const-qualification at the first (and deeper) levels of indirection is to provide you with an ability to create restrictive access paths to objects. I.e. by creating a pointer-to-const you are deliberately and willingly preventing yourself (or someone else) from modifying the pointee, even if the pointee is not constant.

    0 讨论(0)
  • 2020-12-30 23:41
    const object* b = &a;
    

    This means: b is a pointer to a const (read-only) object

    Doesn't say anything about the const-ness of a. It just means b has no right to modify a.

    Also known as low-level const.


    Contrary to the above, top-level const is when the pointer itself is const.

    object *const b = &a;   // b is a const pointer to an object
    
    b = &some_other_object; // error - can't assign b to another object
                            // since b is a const pointer
    
    *b = some_value;        // this is fine since object is non-const
    
    0 讨论(0)
  • 2020-12-30 23:43

    Simply put,

    1. For plain poiters, the result of unary operator * is a reference to pointed-to type.

    2. So, if the type pointed-to is const-qualified, the result is a reference to a constant.

    3. References to constants can bind to any objects, even to mutable objects of otherwise the same type. When you bind a constref to a value, you promise to not ad-hoc modify that value through this refence (you still can do it explicitly though, cast it to a non-const reference).

    4. Likewise, const-pointers can point to objects still modifiable otherwise.

    0 讨论(0)
  • 2020-12-30 23:44

    The type of an expression is just based on the declared types of the variables in the expression, it can't depend on dynamic run-time data. For instance, you could write:

    object a1;
    const object a2;
    const object *b;
    if (rand() % 2 == 0) {
        b = &a1;
    } else {
        b = &a2;
    }
    (*b);
    

    The type of *b is determined at compile-time, it can't depend on what rand() returns when you run the program.

    Since b is declared to point to const object, that's what the type of *b is.

    0 讨论(0)
  • 2020-12-30 23:46

    Because at run-time it might be a const object, meaning that any operations performed on the dereference must be compatible with const. Ignore the fact that in your example it has been pointed to a non-const object and cannot point to anything else, the language doesn't work like that.

    0 讨论(0)
  • 2020-12-30 23:52

    There are plenty of other answers here, but I'm driven to post this because I feel that many of them provide too much detail, wander off topic, or assume knowledge of C++ jargon that the OP almost certainly doesn't have. I think that's unhelpful to the OP and others at a similar phase of their careers so I'm going to try to cut through some of that.

    The situation itself is actually very straightforward. The declaration:

    const SomeClassOrType *p = ...
    

    simply says that whatever p is pointing to cannot be modified through that pointer, and that is useful to ensure that code that gains access to that object via p doesn't modify it when it isn't supposed to. It is most often used in parameter declarations so that functions and methods know whether or not they can modify the object being passed in (*).

    It says nothing at all about the const-ness of what is actually being pointed to. The pointer itself, being just a simple soul, does not carry that information around with it. It only knows that, so far as the pointer is concerned, the object pointed to can be read from but not written to.

    Concrete example (stolen from CiaPan):

    void PrintString (const char *string);
    
    char string [] = "abcde";
    const char *p = string;
    PrintString (p);
    
    void PrintString (const char *ptr_to_string)
    {
        ptr_to_string [0] = 0;   // oops!  but the compiler will catch this, even though the original string itself is writeable
    }
    

    You can just pass string to PrintString directly of course, same difference, because the parameter is also declared const.

    Another way to look at this is that const is information provided by the programmer to help the compiler check the correctness / consistency of the code at compile time. It lets the compiler catch mistakes like the one above, and perhaps perform better optimisations. By the time you actually run your code, it is history.


    (*) The modern idiom is probably to use a const reference, but I don't want to muddy the waters by throwing that into the main discussion.

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