Вообще говоря, бросая T const
к T
с const_cast<>
почти всегда ненужными. Это связано с тем, что постоянный объект преобразуется в непостоянный временной, и это можно безопасно выполнить без приведения.
int const n; // n is a constant int
int x = n; // perfectly safe
Это верно, даже если T
тип указателя. не
int * const n; // n is a constant pointer to an int
int * x = n; // perfectly safe
Однако, если переместить ключевое слово const
на фронт, он не делает постоянный тип указателя, но тип, на который указывает на константу. Таким образом, для нашего примера выше:
const int * n; // n is a pointer to a constant int
int * x = n // error, x is a pointer to an int
Вы можете видеть, что x
указывает на что-то другое, чем то, n
указывает на, и поэтому инициализация будет выполнена. В этом случае инициализация потребует const_cast<>
:
int * x = const_cast<int *>(n);
// cast away the const-ness that n is pointing to
Вы должны сделать это, только если вы знаете, что n
на самом деле modifyable (он не может быть, если указатель к фактической памяти только для чтения), или если вы знаете, что пользователь x
на самом деле не попытается изменить содержимое, на которое указывает n
.
Для примера, вы, кажется, считает, что ваш метод const
должен возвращать указатель на данные, хранящихся на вашем объект таким образом, чтобы данные были изменяемыми вызывающим. То есть, поскольку метод n()
объявлен const
, это означает, что содержимое доступного объекта должно считаться постоянным. Таким образом, n_
представляет собой массив констант int
, который будет распадаться на указатель на константу int
, но вы хотите вернуть указатель на int
.
Если вы намерены изменить n_
, независимо от того, обрабатывается ли объект как постоянный, вы можете объявить это намерение с использованием mutable
. Это приведет к тому, что n_
будет рассматриваться как непостоянный, даже если содержащий объект const
, и поэтому он делает ненужным const_cast
.
class A
{
private:
mutable int n_[10];
public:
/* ... */
int* n() const
{
return n_;
}
};
Да, но не нужно. Вы не возвращаете ссылку, поэтому вызывающий может не модифицировать 'n_', вызывая' n() '. – jxh
Текущий код пытается вернуть 'int *' как 'int'. –
Теперь вы позволите мне сделать это: 'const A a; int * p = a.n(); p [0] = 2; '. Нет, это не безопасно. – chris