константный итератор c ++ stl и константный указатель - PullRequest
1 голос
/ 26 декабря 2011

Я немного запутался в значении этого ключевого слова const. У меня есть такой класс

class ClassA {
public:
    typedef std::tr1::shared_ptr<ClassA> ptr;
    typedef std::tr1::shared_ptr<const ClassA> const_ptr;
    void oper() const;
    void oper();
private:
    .....
};

int main()
{
    std::list<ClassA::const_ptr> const_list;
    .....
    for(std::list<ClassA::const_ptr>::iterator it = const_list.begin();\
    it != const_list.end(); it++)
    {
        (*it)->oper();
    }
    return 0;
}

Я уже получил const версию oper () из приведенного выше кода.Поэтому я не представляю, что я получу, если я заменю std :: list :: iterator на std :: list :: const_iterator.

Ответы [ 2 ]

2 голосов
/ 26 декабря 2011

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

Вы можете подать заявку const:

  • к самому объекту; это означает, что он не может быть изменен;
  • к умному указателю; это означает, что интеллектуальный указатель не может быть изменен, например, невозможно переустановить с помощью reset;
  • в некотором смысле для итератора, использующего const_iterator; это означает, что он выдаст const ссылку на объект, на который он ссылается (=> интеллектуальный указатель), и что его нельзя использовать для изменения последовательности, к которой он относится.
<ч />

Немного расширив:

Помните, что const shared_ptr<const ClassA>& (это то, что вы получаете, разыменовывая const_iterator) отличается от shared_ptr<const ClassA>& (которое вы получаете от обычного iterator): хотя в обоих случаях вы не можете модифицировать указанный объект (из-за того, что shared_ptr относится к const ClassA), на const вы не можете изменить сам shared_ptr, который, например, означает, что вы не можете reset указать его на другой объект, вы не можете назначить ему другое shared_ptr, ...

Помните также, что const версии итераторов, помимо предоставления ссылки const на то, к чему они относятся, также запрещают модифицировать контейнер через них (например, вы не можете erase элемент через const_iterator).

0 голосов
/ 26 декабря 2011

Не уверен, если вы понимаете, что означает void oper() const в class ClassA: В частности, это означает, что ClassA::oper() не может изменять ни одного члена ClassA.

Если ваш выбор итератора или const_iterator будет незначительным, этот выбор будет иметь различные последствия.

...