Как функция-член понимает, что объект получается путем разыменования константного указателя? - PullRequest
2 голосов
/ 05 июня 2019

Я создал указатель const, который указывает на экземпляр объекта abject, динамически распределяемый. Я не мог понять, является ли объект const постоянным или нет.

Сначала я попытался вызвать неконстантную функцию-член с помощью указателя, как и ожидалось, это вызвало ошибку компиляции, потому что (это мое объяснение, я не знаю, верно ли это или нет), этот указатель создан функцией-членом назначен этому константному указателю. Это ничего не дало.

Во-вторых, я попытался разыменовать указатель и вызвать эту неконстантную функцию-член. Я думал, что указатель this, созданный функцией-членом, теперь не будет указателем const, потому что compile не может знать, что объект, возвращаемый p (а именно *p), возвращается указателем const или нет. Оказывается, я ошибся.

Как функция-член понимает это?

#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;
}

Я думал, что строка с меткой 2 не приведет к ошибке компиляции. Это вызывает ошибку компиляции. Сообщение об ошибке:

"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()
         ^~~~~

Ответы [ 3 ]

5 голосов
/ 05 июня 2019

Переменные имеют типы и поэтому могут быть константными или неконстантными, но выражения также имеют типы.Тип (*p) равен const A, и вы не можете вызвать неконстантный метод константного типа.

2 голосов
/ 05 июня 2019

Как уже отмечалось, выражения имеют типы, а тип (* p) является const A. Вы не можете вызывать неконстантную функцию для объекта константного типа, но вы можете вызвать функцию-член const. Функции-члены могут иметь квалификатор const, который будет помечать их как возможность вызывать константные объекты или указатели на константные объекты.

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

Это сделает ваш код компилируемым. и похоже, что это то, что вы намеревались сделать в любом случае.

2 голосов
/ 05 июня 2019

Нет разницы между (1) и (2).(1) является синтаксическим сахаром для (2).Вы должны определить метод print как const, чтобы вызвать его для объекта const.

void print() const { ... }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...