Подтвердить что ты не робот

Как "const" отличается на C и С++?

Как стандартная квалификация по переменным отличается на C и С++?

from: Имеет ли "const" просто означает только для чтения или что-то еще?

"Что вызвало этот вопрос, был этот ответ: qaru.site/info/65307/..., где он утверждает, что const" just "означает" только для чтения "на C. Я думал, что все const означает, независимо от того, был ли он C или С++. Что он имеет в виду?"

4b9b3361

Ответ 1

const в C нельзя использовать для создания постоянных выражений.

Например:

#include <stdio.h>
int main()
{
   int i = 2;
   const int C = 2;
   switch(i)
   {
      case C  : printf("Hello") ;
      break;

      default : printf("World");
   }
}

не работает в C, потому что метка case не сводится к целочисленной константе.

Ответ 2

const означает, что вы обещаете не изменять эту переменную. Он все еще может быть изменен.

class A {
  public:
    A(const int& a);
    int getValue() const;
    void setValue(int b);
  private:
    const int& a;
};
A::A(a) : a(a) {}
int A::getValue() const {
    return a;
}
void A::setValue(int b) {
    a = b;  // error
}

int main() {
    int my_a = 0;
    A a(my_a);
    std::cout << a.getValue() << std::endl;  // prints 0
    my_a = 42;
    std::cout << a.getValue() << std::endl;  // prints 42
}

Без метода A::* может измениться a, но main может. Это очень похоже на C и С++.


У С++ есть несколько (ограниченных) способов обойти const, которые должны препятствовать неправильному отбрасыванию const программистам.

Возьмите класс, подобный этому.

class A {
  public:
    A();
    int getValue();
  private:
    static int expensiveComputation();
    int cachedComputation;
};

A::A() : cachedComputation(0) {}

A::getValue() {
    if (cachedComputation == 0)
        cachedComputation = expensiveComputation();
    return cachedComputation;
}

cachedComputation неявно означает this->cachedComputation. Помните об этом.

int main() {
    A a1;
    const A a2;
    std::cout << a1.getValue() << std::endl;
    std::cout << a2.getValue() << std::endl;  // error
}

a2.getValue() является незаконным, так как на const A a2 вызывается метод не const. Можно отбросить const -ness...

    std::cout << ((A&)a2).getValue() << std::endl;            // C-style cast
    std::cout << const_cast<A&>(a2).getValue() << std::endl;  // C++-style cast

Второй предпочтительнее, потому что компилятор проверяет, что только const -ness ливается, ничего больше. Однако это все еще не идеально. Вместо этого в класс должен быть добавлен новый метод.

class A {
  public:
    int getValue() const;
};

A::getValue() const {
    if (cachedComputation == 0)
        cachedComputation = expensiveComputation();  // error
    return cachedComputation;
}

Теперь существует метод const, поэтому a2.getValue() в порядке. Однако конечный const означает, что методу присваивается указатель const A *this, а не указатель A *this, как обычно, что делает this->cachedComputation a const int &, который не может быть мутирован.

const_cast может быть применен внутри метода, но лучше было бы изменить это одно членное объявление.

class A {
  private:
    mutable int cachedComputation;
};

Теперь даже с const A *this, this->cachedComputation может быть изменен без кастинга.