3

I created a const pointer which points to an instance of abject allocated dynamically.I could not understand the object itself is const or not.

Firstly I tried to call a non-const member function by using pointer, as expected it caused a compile error because (it is my explanation, don't know if it is true or not) this pointer created by the member function is assigned to that const pointer. It did not yield anything.

Secondly I tried to dereference the pointer and call that non-const member function. I thought that the this pointer created by member function now will not be a const pointer because compile can not know the object returned by p (namely *p) is returned by a const pointer or not. It turns out that I was mistaken.

How does member-function understand that ?

#include<iostream>

class A
{
    int a=4;
public:
    A()
    {}

 void   print()
    {
        std::cout<<a<<std::endl;
    }
};


int main()
{
    const A* p = new A();  

   p->print(); //1 causes compile error
   (*p).print(); //2 causes compile error


  return 0;
}

I thought the line labelled as 2 will not create a compile error. It causes a compile error.The error message is:

"a.cpp: In function ‘int main()’:
a.cpp:21:13: error: passing ‘const A’ as ‘this’ argument discards qualifiers [-fpermissive]
    p->print(); //1 causes compile error
             ^
a.cpp:10:9: note:   in call to ‘void A::print()’
  void   print()
         ^~~~~
a.cpp:22:15: error: passing ‘const A’ as ‘this’ argument discards qualifiers [-fpermissive]
    (*p).print(); //2 causes compile error
               ^
a.cpp:10:9: note:   in call to ‘void A::print()’
  void   print()
         ^~~~~

Stack Danny
  • 7,754
  • 2
  • 26
  • 55
  • 1
    I fail to understand what you are confused about. If one dereferences `const A*`, one is left with `const A`, no? – Algirdas Preidžius Jun 05 '19 at 13:49
  • `p` is a pointer to `const` object, while `print` is not marked as const function. What is surprising? – SergeyA Jun 05 '19 at 13:50
  • @SergeyA It's surprising if you think of const correctness as being enforced on a primary-expression basis rather than through the type system. – Sneftel Jun 05 '19 at 13:51
  • 1
    then const A* p = new A(); and const A* p = new const A(); has no difference right ? – no one ever Jun 05 '19 at 13:52
  • They are *slightly* different, but not in a particularly useful way, and I've never seen `new const A` in real code. See https://stackoverflow.com/questions/1927477/can-a-heap-allocated-object-be-const-in-c . – Sneftel Jun 05 '19 at 13:54
  • 1
    why does the object that created is type-casted to const ? I mean I create a non-const integer and const integer that points to that integer . – no one ever Jun 05 '19 at 13:55
  • 2
    Because you did it when you assigned it to a variable of type `const A*`. C++ lets you implicitly cast a non-const object to a const type, since that's a completely safe thing to do. – Sneftel Jun 05 '19 at 13:57
  • 1
    @Sneftel thanks, now I understand :) – no one ever Jun 05 '19 at 13:57
  • please include error messages verbatim instead of paraphrasing them. Calling it "classic" is a bit misplaced imho, what is classic about it? – 463035818_is_not_an_ai Jun 05 '19 at 14:22
  • 1
    @formerlyknownas_463035818 okey – no one ever Jun 05 '19 at 14:36

3 Answers3

6

Variables have types and can therefore be const or non-const, but expressions have types too. The type of (*p) is const A, and you can't call a non-const method of a const type.

Sneftel
  • 40,271
  • 12
  • 71
  • 104
  • Hmm you say the object created by new is const ? Why because I can point a const integer pointer to a non-const integer . Is there a reason ? ---- I got my Answer ---- – no one ever Jun 05 '19 at 13:57
3

There is no difference between (1) and (2). (1) is syntax sugar for (2). You should define the print method as const in order to call it for const object.

void print() const { ... }
Simo Simov
  • 97
  • 5
3

As it has already been noted, expressions have types and the type of (*p) is const A. You cannot call a non-const function on an object of a const type but you can call const member function. Member functions can have a const qualifier which will mark them to be able to be invoked on const objects or pointers to const objects.

void print() const
{
   std::cout<<a<<std::endl;
}

This will make your code compile. and it looks like this is what you intended to do anyway.

shargors
  • 2,147
  • 1
  • 15
  • 21