Const iterator, private struct.

Discussion in 'C++' started by swhite, Aug 14, 2006.

  1. swhite

    swhite Guest

    Hi,

    Sorry, not very clear from the title but wasn't sure what to call it.
    I was experimenting with the following in GCC 4.0.1 and didn't achieve
    what I expected. I was trying to keep the internal class private, to
    prevent creation, but also in the hope it might achieve something like
    when you use "class <foo>;" to early declare to allow pointer passing,
    but cannot access contents.

    Also I passed out a const iterator containing this object expecting it
    to make what it was iterating over const, but gcc allows me to change
    it.

    Just wondered what I should actually expect (found behaviour was
    correct?) and anything close (if possible) to roughly achieve what I
    was expecting.

    #include <map>
    #include <string>

    class A
    {
    private:
    struct Test
    {
    int a;
    int b;
    };
    typedef std::map<std::string,Test *> Test2;

    public:
    typedef const Test2::const_iterator Test3;

    private:
    Test2 m_test;

    public:
    Test3 foo () { return m_test.end (); }
    };

    int main ()
    {
    A a;
    A::Test3 test = a.foo ();
    // Accesses object of private type...
    // Didn't want, hoping for compiler error
    int b = (*test).second->a;
    (*test).second->a = 1; // modified const...
    return 0;
    }

    Regards,
    Simon
     
    swhite, Aug 14, 2006
    #1
    1. Advertising

  2. swhite wrote:
    > Hi,
    >
    > Sorry, not very clear from the title but wasn't sure what to call it.
    > I was experimenting with the following in GCC 4.0.1 and didn't achieve
    > what I expected. I was trying to keep the internal class private, to
    > prevent creation, but also in the hope it might achieve something like
    > when you use "class <foo>;" to early declare to allow pointer passing,
    > but cannot access contents.
    >
    > Also I passed out a const iterator containing this object expecting it
    > to make what it was iterating over const, but gcc allows me to change
    > it.
    >
    > Just wondered what I should actually expect (found behaviour was
    > correct?) and anything close (if possible) to roughly achieve what I
    > was expecting.
    >
    > #include <map>
    > #include <string>
    >
    > class A
    > {
    > private:
    > struct Test
    > {
    > int a;
    > int b;
    > };
    > typedef std::map<std::string,Test *> Test2;
    >
    > public:
    > typedef const Test2::const_iterator Test3;
    >
    > private:
    > Test2 m_test;
    >
    > public:
    > Test3 foo () { return m_test.end (); }
    > };
    >
    > int main ()
    > {
    > A a;
    > A::Test3 test = a.foo ();
    > // Accesses object of private type...
    > // Didn't want, hoping for compiler error
    > int b = (*test).second->a;
    > (*test).second->a = 1; // modified const...
    > return 0;
    > }
    >
    > Regards,
    > Simon
    >


    Well, the reason is const_iterator does not allow you to modify the
    structure of the container, but it says nothing with regards to the
    object themselves. To achieve what you want you need to do that:

    #include <string>
    #include <map>

    class A
    {
    public:
    struct Test
    {
    int a;
    int b;
    };
    typedef std::map<std::string,const Test *> Test2;
    typedef const Test2::const_iterator Test3;

    Test3 foo () { return m_test.begin (); }
    void add( const std::string& s, const Test& t )
    {
    m_test[ s ] = new Test( t );
    }

    void modify( const std::string& s, const Test& nt )
    {
    Test* t = const_cast<Test*>( m_test[ s ] );
    *t = nt;
    }
    private:

    Test2 m_test;

    };

    int main ()
    {
    A a;
    A::Test t = {1,2};
    a.add( "toto", t );
    A::Test3 test = a.foo ();
    // Accesses object of private type...
    // Didn't want, hoping for compiler error
    t.b = 1;
    a.modify( "toto", t );
    int b = test->second->a;
    test->second->a = 1; // modified const...
    return 0;
    }

    Pierre
     
    Pierre Barbier de Reuille, Aug 14, 2006
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Chris Fogelklou
    Replies:
    36
    Views:
    1,440
    Chris Fogelklou
    Apr 20, 2004
  2. Replies:
    6
    Views:
    696
    Jim Langston
    Oct 30, 2005
  3. Replies:
    11
    Views:
    1,151
  4. Javier
    Replies:
    2
    Views:
    622
    James Kanze
    Sep 4, 2007
  5. 0m
    Replies:
    26
    Views:
    1,171
    Tim Rentsch
    Nov 10, 2008
Loading...

Share This Page