Константное размещение, чтобы остановить редактирование данных указателя с помощью boostshared_ptr

StackOverflow https://stackoverflow.com//questions/24050425

  •  21-12-2019
  •  | 
  •  

Вопрос

Итак, Википедия говорит мне (я правильно считаю), что для прекращения редактирования данных указателя и самого указателя мне следует сделать следующее:

void function(int const * const var)

Это то же самое, что и эта функция:

void function(const int * const var)

И в таком случае, почему это разрешено?Потому что я знаю, что вы не можете этого сделать из-за повторяющейся ошибки компиляции const:

void function(const int const * const var)

По сути, я хочу сделать то же самое с указателем повышения.Сделал бы я это:

void function(const boost::shared_ptr<int> const var)

И как это повлияет на мою способность перебирать, скажем, общий указатель на вектор?Могу ли я сделать это с этим охранником:

void function(const boost::shared_ptr<std::vector<int>> const var)
{
    for (unsigned int i = 0; i < var->size(); ++i)
    {
        std::cout << var[i];
    }
}

Дополнение:После ответа Брайана

Итак, если я создам такой указатель:

boost::shared_ptr<vector<int>> lala

И я использую его в этой функции:

function (const boost::shared_ptr<std::vector<const int>> var)

это сработает?

Это было полезно?

Решение

Да, int const * const var такой же как const int * const var.Вы можете положить const до или после изменяемого типа по «историческим причинам».Видеть http://www.stroustrup.com/bs_faq2.html#constplacement

Для объекта смарт-указателя вы действительно не можете сделать

const boost::shared_ptr<int> const

потому что оба consts изменяют тот же тип.Вместо этого вы хотите

const boost::shared_ptr<const int>

Первый const предотвращает изменение самого указателя (то есть, переназначен, чтобы указать на другой int) и const в параметре шаблона указывается объект operator* вернуть const int&, что предотвращает модификацию int указал на.

Это не предотвращает перебор вектора или другого контейнера описанным вами способом по той же причине, по которой вы все равно можете перебирать const вектор нормально.

Редактировать в ответ на редактирование вопроса:

Это работает:

void f(const boost::shared_ptr<const std::vector<int> > var);
// ...
boost::shared_ptr<vector<int> > lala;
f(lala);

Первый const в параметре вообще не влияет на передачу параметра;он только сообщает самой функции не изменять параметр.Причина, по которой мы можем добавить const в параметре шаблона является то, что boost::shared_ptr<T> может быть инициализирован из boost:shared_ptr<U> где T и U не обязательно одного и того же типа, если U* неявно конвертируется в T*.Если T такой же как U кроме как при большей cv-квалификации, как в этом случае конвертация возможна.

Не делай std::vector<const int>.Я почти уверен, что это не законно.(По крайней мере, каждый раз, когда я это пробовал, я получал несколько экранов с ошибками компиляции.)

Другие советы

const до или после того же, что int одинаково так:

int const * var
.

и

const int * var
.

одинаковы и означают, что значение, указанное на нельзя изменить

const после того, как * означает, что указатель не может быть переназначен.

Если я правильно понимаю, вы хотели бы сделать вектор Const.Если это так, что синтаксис будет так:

void function(const boost::shared_ptr<const std::vector<int>>& var)
.

Умный указатель пропускается ссылкой Const, потому что это дешевле, чем передавать умный указатель по значению и имеет тот же эффект.Объект, указанный на умный указатель, неизменно, объявляющий тип его указывает на POST.

Вы правильно рассуждали, что const shared_ptr<Foo> не делает FOO Const Object.Эта «лазейка» описывается на Wikipedia .Вместо этого вам нужно изменить тип указателя, хранящегося Boost :: Shared_PTR.Это можно сделать в самом аргументе шаблона:

void function(const boost::shared_ptr<const std::vector<int>>& var)

Boost :: Shared_PTR имеет Copy-Constructor, который позволяет копировать Const-Type, который будет скопирован из не-постоянного типа.Противоположное должно быть невозможно.

До или после?

Следующие две строки семантически эквивалентны: обе объявляют указатель, значение которого нельзя изменить, который ссылается на int это невозможно изменить.

int const * const p1 = ...; 
const int * const p2 = ...;

А константа ключевое слово привязывается к тому, что находится непосредственно слева, пока не слева нет ничего, и в этом случае он будет охватывать все, что находится справа.


Чем больше const, лучше?

 typedef boost::shared_ptr<int> shared_int_ptr;

 const shared_int_ptr const p3; // ill-formed

Выше определение типа это сделано для того, чтобы было легче увидеть это boost::shared_ptr<int> это одно имя, и поэтому мы не можем добавить const с обеих сторон;дубликат константы (как вы упомянули) не являются законными C++.

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


Раньше мы это писали boost::shared_ptr должен обернуться вокруг int, но поскольку мы хотим сделать обернутый тип const, хорошо..давайте завернем общий_ptr вокруг того, что мы хотим:

void func (const boost::shared_ptr<const int> foo);

В приведенном выше func не способен изменить foo, ни int на который ссылается foo.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top