How to make it really constant?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • shuisheng

    How to make it really constant?

    Dear All,

    I have a question. Assume

    struct A
    {
    int *p, *q;
    };

    struct B
    {
    A a;

    const struct& GetA() const
    {
    return a;
    }
    };

    I hope B::GetA() cannot change p, q pointed values, but it can, such
    as

    *(B::GetA().p) = 3;

    How can I make it really constant? One way may be defining p and q as
    follows
    const int * p;
    const int * q;

    Whenever p, q pointed values want to change in class/struct A, do the
    const_cast. But this is too cumbersome.

    I remember a constant std::vector cannot change its values, even
    thought it is also implemented by a inner pointer. How does
    std::vector make the values constant?

    Thanks and best regards,

    Shuisheng
  • tony_in_da_uk@yahoo.co.uk

    #2
    Re: How to make it really constant?

    On Sep 19, 3:12 pm, shuisheng <shuishen...@ya hoo.comwrote:
    Dear All,
    >
    I have a question. Assume
    >
    struct A
    {
    int *p, *q;
    >
    };
    >
    struct B
    {
    A a;
    >
    const struct& GetA() const
    {
    return a;
    }
    >
    };
    >
    I hope B::GetA() cannot change p, q pointed values, but it can, such
    as
    >
    *(B::GetA().p) = 3;
    >
    How can I make it really constant? One way may be defining p and q as
    follows
    const int * p;
    const int * q;
    >
    Whenever p, q pointed values want to change in class/struct A, do the
    const_cast. But this is too cumbersome.
    If you want this kind of control, you should make A a class, with p
    and q private. Then provide const A& get_a() const and A& get_a()
    members etc..

    Tony

    Comment

    • anon

      #3
      Re: How to make it really constant?

      tony_in_da_uk@y ahoo.co.uk wrote:
      On Sep 19, 3:12 pm, shuisheng <shuishen...@ya hoo.comwrote:
      >Dear All,
      >>
      >I have a question. Assume
      >>
      >struct A
      >{
      > int *p, *q;
      >>
      >};
      >>
      >struct B
      >{
      > A a;
      >>
      > const struct& GetA() const
      > {
      > return a;
      > }
      >>
      >};
      >>
      >I hope B::GetA() cannot change p, q pointed values, but it can, such
      >as
      >>
      >*(B::GetA(). p) = 3;
      >>
      >How can I make it really constant? One way may be defining p and q as
      >follows
      >const int * p;
      >const int * q;
      >>
      >Whenever p, q pointed values want to change in class/struct A, do the
      >const_cast. But this is too cumbersome.
      >
      If you want this kind of control, you should make A a class, with p
      and q private. Then provide const A& get_a() const and A& get_a()
      members etc..
      With this solution you can still change values. In the
      const A& get_a() const
      method, you couldn't change pointers, but could still change the value
      they point to.

      Only way is to change struct A

      Comment

      • Jim Z. Shi

        #4
        Re: How to make it really constant?


        shuisheng wrote:
        Dear All,
        >
        I have a question. Assume
        >
        struct A
        {
        int *p, *q;
        };
        add an assist method in you struct A.

        i don't quite catch your program's requires, but you can try something
        like this anyway.

        cheers & hth,
        Jim

        //=============== =============== =============== =======
        #include <iostream>

        using namespace std;

        struct A
        {
        int a;
        int* pa;
        const int* const get_pa() const
        {
        return pa;
        }
        };

        struct B
        {
        A a;

        const A& getA() const
        {
        return a;
        }
        };

        int main()
        {
        B b;
        int i = 4;
        // b.getA().a = 3;
        *(b.getA().get_ pa()) = i; // fail
        *(b.getA().pa) = i; // OK
        return 0;
        }

        Comment

        • tony_in_da_uk@yahoo.co.uk

          #5
          Re: How to make it really constant?

          On Sep 19, 3:12 pm, shuisheng <shuishen...@ya hoo.comwrote:
          struct A { int *p, *q; };
          >
          struct B
          {
          A a;
          const struct& GetA() const { return a; }
          };
          >
          I hope B::GetA() cannot change p, q pointed values, but it can, such
          as
          >
          *(B::GetA().p) = 3;
          >
          tony_in_da...@y ahoo.co.uk wrote:
          If you want this kind of control, you should make A a class, with p
          and q private. Then provide const A& get_a() const and A& get_a()
          members etc..
          >
          On Sep 19, 4:31 pm, anon <a...@no.invali dwrote:
          With this solution you can still change values. In the
          const A& get_a() const
          method, you couldn't change pointers, but could still change the value
          they point to.
          >
          Only way is to change struct A [snip]
          "If you want this kind of control, you should make A a class, with p
          and q private."...

          struct A
          {
          private:
          int *p, *q;
          };

          "Then provide const A& get_a() const and A& get_a() members etc.."...

          struct B
          {
          A a;
          const struct& GetA() const
          {
          return a;
          }

          struct& GetA()
          {
          return a;
          }
          };

          Clearly, there's nothing public to access in a. By implication, you
          must expose p and q similarly...

          struct A
          {
          const int* get_p() const { return p; }
          int* get_p() { return p; }

          const int* get_q() const { return q; }
          int* get_q() { return q; }

          private:
          int *p, *q;
          };

          And there you have it.

          Tony

          Comment

          • blargg

            #6
            Re: How to make it really constant?

            In article
            <8f8157c0-2671-4473-ba3a-992b92e2f73f@d1 g2000hsg.google groups.com>,
            shuisheng <shuisheng75@ya hoo.comwrote:
            struct A
            {
            int *p, *q;
            };
            >
            struct B
            {
            A a;
            >
            const struct& GetA() const
            {
            return a;
            }
            };
            >
            I hope B::GetA() cannot change p, q pointed values, but it can, such
            as
            >
            *(B::GetA().p) = 3;
            >
            How can I make it really constant? One way may be defining p and q as
            follows
            const int * p;
            const int * q;
            >
            Whenever p, q pointed values want to change in class/struct A, do the
            const_cast. But this is too cumbersome.
            >
            I remember a constant std::vector cannot change its values, even
            thought it is also implemented by a inner pointer. How does
            std::vector make the values constant?
            You could write a smart pointer helper class that propagates const one
            level down:

            template<typena me T>
            class Ptr {
            T* p;
            public:
            Ptr& operator = ( T* rhs ) { p = rhs; return *this; }

            T & operator * () { return *p; }
            T const& operator * () const { return *p; }

            T * operator -() { return p; }
            T const* operator -() const { return p; }
            // ...
            };

            struct A { Ptr<intx; };

            int f( A& a )
            {
            a.x = new int; // OK
            *a.x = 1234; // OK
            return *a.x; // OK
            }

            int fc( A const& a )
            {
            a.x = new int; // error
            *a.x = 1234; // error
            return *a.x; // OK
            }

            Comment

            Working...