Dereferencing a pointer to constant

前端 未结 10 561
深忆病人
深忆病人 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:52

    By writing

    const object* b = &a;
    

    you declare that b is a pointer (*) to a const of type object, to which you then assign the address of a. a is of type object (but not const); you are permitted to use the adress of the non-const object in place of an adress of an const object.

    When you dereference * b however, the compiler can only go according to your declaration - thus *b is a const object (however you can still modify a as you like, so beware of thinking that the object b points to cannot change - it mere cannot be changed via b)

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

    Here’s a specific example of why it is the way it is. Let’s say you declare:

    int a[] = {1, 2, 3};
    constexpr size_t n_a = sizeof(a)/sizeof(a[0]);
    
    extern int sum( const int* sequence, size_t n );
    sum_a = sum( a, n_a );
    

    Now you implement sum() in another module. It doesn’t have any idea how the original object you’re pointing to was declared. It would be possible to write a compiler that tagged pointers with that information, but no compilers in actual use today do, for a number of good reasons.¹

    Inside sum(), which might be in a shared library that cannot be recompiled with whole-program optimization, all you see is a pointer to memory that cannot be altered. In fact, on some implementations, trying to write through a pointer to const might crash the program with a memory-protection error. And the ability to reinterpret a block of memory as some other type is important to C/C++. For example, memset() or memcpy() reinterprets it as an array of arbitrary bytes. So the implementation of sum() has no way to tell the provenance of its pointer argument. As far as it’s concerned, it’s just a pointer to const int[].

    More importantly, the contract of the function says that it’s not going to modify the object through that pointer.² It could simply cast away the const qualifier explicitly, but that would be a logic error. If you’re declaring a pointer const, it’s like engaging the safety on your gun: you want the compiler to stop you from shooting yourself in the foot.

    ¹ Including extra instructions to extract the address from a pointer, extra memory to store them, compatibility with the standard calling convention for the architecture, breaking a lot of existing code that assumes things like long being able to hold a pointer, and the lack of any benefit.

    ² With the pedantic exception of mutable data members.

    0 讨论(0)
  • 2020-12-31 00:04
    const object* b = &a;
    

    b will treat what it points to as const, i.e. it cannot change a

    object* const b = &a;
    

    b itself is const, i.e. it cannot point to other object address, but it can change a

    0 讨论(0)
  • 2020-12-31 00:05

    Because the const keyword means 'you can not modify that object' rather than 'the object can not be modified'.

    This is useful when you pass an object to some function to use the object's value only, but but not to modify it:

    // We expect PrintMyString to read the string
    // and use its contents but not to modify it
    
    void PrintMyString(const char *string);
    
    void myfunction(int number)
    {
        // build and print a string of stars with given length
        if(number>0 && number<=16]
        {
            char string[17];
            int i;
            for(i=0, i<number; i++)
                string[i] = '*';
            string[number] = '\0';
    
            PrintMyString(string);
        }
    }
    

    The function PrintMyString will get an array of characters, but the array will be passed as 'read only' to the function. The array is certainly modifiable within the owning function, but the PrintMyString can only read what it gets and not alter the contents.

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