Newbie question: С++ const для неконстантной конверсии
В наши дни меня действительно раздражает ключевое слово const
, поскольку я не совсем знаком с ним. У меня был вектор, в котором хранятся все константные указатели, такие как vector<const BoxT<T> *> *Q_exclude
, а в конструкторе другого класса мне нужен элемент в этой очереди, который должен быть передан как параметр и назначить ему неконстантный член. Мой вопрос:
Как назначить переменную const переменной non-const? Я знаю, что это не имеет смысла, поскольку в конце концов, const является константой и не должен изменяться никаким средним значением. Но эта раздражающая переменная участника ДЕЙСТВИТЕЛЬНО должна быть изменена во время процесса! Я мог бы также изменить тип данных в векторе, чтобы он не был const, но это было бы слишком большой работой. Или кто-нибудь знает, как избежать такой ситуации?
Ответы
Ответ 1
Объект const
можно присвоить объекту не const
. Поскольку вы копируете и тем самым создаете новый объект, const
не нарушается.
Так же:
int main() {
const int a = 3;
int b = a;
}
Он отличается, если вы хотите получить указатель или ссылку на исходный объект const
:
int main() {
const int a = 3;
int& b = a; // or int* b = &a;
}
// error: invalid initialization of reference of type 'int&' from
// expression of type 'const int'
Вы можете использовать const_cast
, чтобы взломать безопасность типа, если вам действительно нужно, но помните, что вы делаете именно это: избавляетесь от безопасности типа. Он еще undefined может изменить a
через b
в нижеприведенный пример:
int main() {
const int a = 3;
int& b = const_cast<int&>(a);
b = 3;
}
Несмотря на то, что он компилируется без ошибок, может случиться что-то, включая открытие черной дыры или перенос всех ваших с трудом заработанных сбережений на мой банковский счет.
Если вы пришли к тому, что, по вашему мнению, необходимо для этого, я бы срочно пересмотрел ваш дизайн, потому что с ним что-то не так.
Ответ 2
Изменение постоянного типа приведет к Undefined Поведение.
Однако, если у вас есть первоначально неконстантный объект, на который указывает указатель на константу или ссылающийся на ссылку-на-const, вы можете использовать const_cast, чтобы избавиться от эта константа.
Изгнание созвездия считается злым, и следует избегать not. Вы должны рассмотреть возможность изменения типа указателей, которые вы используете в векторе, для не-const, если вы хотите изменить данные через него.
Ответ 3
Фактический код, чтобы отбросить константу указателя, будет:
BoxT<T> * nonConstObj = const_cast<BoxT<T> *>(constObj);
Но обратите внимание, что это действительно обман. Лучшим решением будет либо выяснить, почему вы хотите изменить объект const, так и перепроектировать код, чтобы вам не пришлось.... или удалить объявление const из вашего вектора, если окажется, что вы не действительно хотят, чтобы эти элементы были доступны только для чтения.