Почему константность не применяется для указателей? - PullRequest
0 голосов
/ 02 октября 2018

Рассмотрим следующий фрагмент кода:

class A
{
public:

    void nonConstFun()
    {

    }
};

class B
{
private:

    A a_;
    A * pA_;

public:

    void fun() const
    {
        pA_->nonConstFun();
        //a_.nonConstFun(); // Gives const related error
    }
};

int main()
{
    B b;
    b.fun();
}

Здесь я ожидаю, что компилятор не выполнит компиляцию из-за отсутствия константности для вызова A::nonConstFun() внутри B::fun() независимо от типа объекта A.

Однако компилятор жалуется на объект, но не на указатель.Зачем?Я использую VS2017 на Windows 10.

Ответы [ 2 ]

0 голосов
/ 02 октября 2018

Другие ответы объясняют T* const против T const *, что и происходит.Но важно понять значение этого за пределами простого синтаксиса.

Когда у вас есть T* внутри структуры, указатель находится внутри объекта, но указанный объект физически находится вне структуры.Вот почему для const-объекта с элементом T* не разрешается изменять указатель, но разрешается изменять заостренный объект - поскольку физически заостренный объект находится за пределами охватывающего объекта.

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

Недостатком C ++ является то, что он не предлагает простой способ выразить логическую константу, как указано выше (что вы на самом деле ожидали от своего кода).

Это известно, и для этой конкретной цели естьэкспериментальный класс, который еще не является стандартным propagate_const

std :: эксперимент :: ::ateate_const - это распространяющая константу оболочка для указателей и объектов, похожих на указатели.Оболоченный указатель рассматривается как указатель на const при доступе через путь доступа к const, отсюда и имя.

struct B
{
    A a_;
    std::experimental::propagate_const<A *> pA_;

   void fun()
    {
        pA_->nonConstFun(); // OK
    }
    void fun() const
    {
        // pA_->nonConstFun(); // compilation error
    }
};
0 голосов
/ 02 октября 2018

Это является принудительным.

Если вы попытаетесь изменить указатель, компилятор не позволит вам.

Однако указатель указывает на то, чтодругой разговор.

Помните, T* const и T const* - это не одно и то же!

Вы можете защитить это, либо фактически сделав это A const*, либо просто написав свою функциюсоответствующим образом.

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