Const Qualifier question

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

    Const Qualifier question

    Dear Readers,
    I am porting my existing C code to C++. In my existing code
    there are numerous functions that has been defined with CONST
    qualifier. For eg. foo(const DATA_TYPE *x); DATA_TYPE is some typedef
    structure and offcourse x is a pointer to it. Needless to say my
    intention for writing such functions in C was to protect the accident
    write to x's content. So far so good. While porting to C++, I've mada
    DATA_TYPE as class and I want to retain the sanity of existing C
    function that has Const qualifier. However am having some trouble,
    which is illustrated in the sample code below :

    #include <iostream>
    typedef struct _temp {
    int a;
    char b;
    short int c;
    }TEMP_STRUCT; // Define some temporary structure for illustration
    purpose

    class data_type
    {
    public :
    void *address;
    data_type(void) ;
    ~data_type();
    void init_data_type( );
    void * getAddress() ;
    };

    data_type::data _type()
    {
    address = new TEMP_STRUCT;
    }
    inline void * data_type::getA ddress()
    {
    return((void *)address);
    }
    inline void data_type::init _data_type()
    {
    address->a=1;
    address->b='a';
    address->c=1;
    };

    void foo(const data_type *);

    #define GET_ADDRESS(obj ect) ((object)->getAddress() )

    int main(int argc, char *argv[])
    {
    data_type temp_object;
    temp_object.ini t_data_type();
    foo(&temp_objec t);
    }
    void foo(const data_type *temp_object)
    {
    using namespace std;

    if (((TEMP_STRUCT *)(GET_ADDRESS( temp_object)))->a)
    cout << "Test Passed";
    //Error error: passing `const
    //data_type' as `this' argument of `void* data_type::getA ddress
    //()' discards qualifiers
    }

    In C functions like foo() were called with "const TEMP_STRUCT *"
    argument therefore compiler took care of any accident write to its
    content. However in C++ this argument is changed to a class, which
    fetches the address to TEMP_STRUCT, however, I still want the class to
    return the address in such a way that the content of address can't be
    modified inside the function. However, above sample code doesn't work
    because foo is called with const qualifier, therefore complier
    complains, if I try to access any of its member function. However if
    get_address is defined as " void * getAddress() const", the compiler
    error goes away, however, const qualifier inside foo also looses its
    meaning i.e. you can write to the content of data type.
    My question is how can this class return address whose content can't
    be modified and at the same time I dont have to change the prototype
    of my existing C functions.
    Am sorry, if this question doesn't belong here or the information I've
    provided is not sufficient.
    Thanks for your time,
    Mahesh
  • Mike Wahler

    #2
    Re: Const Qualifier question

    "Mahesh Tomar" <tomar27@msn.co m> wrote in message
    news:4647d063.0 409010800.5cf2b 29d@posting.goo gle.com...

    See below.
    [color=blue]
    > Dear Readers,
    > I am porting my existing C code to C++. In my existing code
    > there are numerous functions that has been defined with CONST
    > qualifier. For eg. foo(const DATA_TYPE *x); DATA_TYPE is some typedef
    > structure and offcourse x is a pointer to it. Needless to say my
    > intention for writing such functions in C was to protect the accident
    > write to x's content. So far so good. While porting to C++, I've mada
    > DATA_TYPE as class and I want to retain the sanity of existing C
    > function that has Const qualifier. However am having some trouble,
    > which is illustrated in the sample code below :
    >
    > #include <iostream>
    > typedef struct _temp {
    > int a;
    > char b;
    > short int c;
    > }TEMP_STRUCT; // Define some temporary structure for illustration
    > purpose
    >
    > class data_type
    > {
    > public :
    > void *address;
    > data_type(void) ;
    > ~data_type();
    > void init_data_type( );
    > void * getAddress() ;[/color]

    void *getAddress() const;
    [color=blue]
    > };
    >
    > data_type::data _type()
    > {
    > address = new TEMP_STRUCT;
    > }
    > inline void * data_type::getA ddress()[/color]

    inline void * data_type::getA ddress() const
    [color=blue]
    > {
    > return((void *)address);
    > }
    > inline void data_type::init _data_type()
    > {
    > address->a=1;
    > address->b='a';
    > address->c=1;
    > };
    >
    > void foo(const data_type *);
    >
    > #define GET_ADDRESS(obj ect) ((object)->getAddress() )
    >
    > int main(int argc, char *argv[])
    > {
    > data_type temp_object;
    > temp_object.ini t_data_type();
    > foo(&temp_objec t);
    > }
    > void foo(const data_type *temp_object)
    > {
    > using namespace std;
    >
    > if (((TEMP_STRUCT *)(GET_ADDRESS( temp_object)))->a)
    > cout << "Test Passed";
    > //Error error: passing `const
    > //data_type' as `this' argument of `void* data_type::getA ddress
    > //()' discards qualifiers
    > }[/color]

    Look up 'const member function'.

    -Mike


    Comment

    • Mahesh Tomar

      #3
      Re: Const Qualifier question

      Mike,
      Thanks for your time. However, I too have mentioned the solution in
      my original e-mail where I stated "if member function,get_ad dress, is
      defined as " void * getAddress() const", the compiler error goes away,
      however, const qualifier inside foo also looses its meaning i.e. you
      can write to the content of data type."
      Putting a const qualifier at the end of function will make the error
      go away, however, if I do something like this
      void foo(const data_type *temp_object)
      {
      using namespace std;

      // This statement below will modify the content of temp_object and
      that is
      // not the intention.
      ((TEMP_STRUCT *)(GET_ADDRESS( temp_object)))->a = 2;
      cout << ((TEMP_STRUCT *)(GET_ADDRESS( temp_object)))->a;
      }
      If you see above, the intent of foo () function which was suppose to
      protect any accidental write to the content of temp_object is lost. In
      short I want to maintain the sanity of such functions (that am porting
      to C++).
      Any insight into this will be really appreciated.

      Thanks,
      Mahesh

      "Mike Wahler" <mkwahler@mkwah ler.net> wrote in message news:<1JmZc.467 2$w%6.1531@news read1.news.pas. earthlink.net>. ..[color=blue]
      > "Mahesh Tomar" <tomar27@msn.co m> wrote in message
      > news:4647d063.0 409010800.5cf2b 29d@posting.goo gle.com...
      >
      > See below.
      >[color=green]
      > > Dear Readers,
      > > I am porting my existing C code to C++. In my existing code
      > > there are numerous functions that has been defined with CONST
      > > qualifier. For eg. foo(const DATA_TYPE *x); DATA_TYPE is some typedef
      > > structure and offcourse x is a pointer to it. Needless to say my
      > > intention for writing such functions in C was to protect the accident
      > > write to x's content. So far so good. While porting to C++, I've mada
      > > DATA_TYPE as class and I want to retain the sanity of existing C
      > > function that has Const qualifier. However am having some trouble,
      > > which is illustrated in the sample code below :
      > >
      > > #include <iostream>
      > > typedef struct _temp {
      > > int a;
      > > char b;
      > > short int c;
      > > }TEMP_STRUCT; // Define some temporary structure for illustration
      > > purpose
      > >
      > > class data_type
      > > {
      > > public :
      > > void *address;
      > > data_type(void) ;
      > > ~data_type();
      > > void init_data_type( );
      > > void * getAddress() ;[/color]
      >
      > void *getAddress() const;
      >[color=green]
      > > };
      > >
      > > data_type::data _type()
      > > {
      > > address = new TEMP_STRUCT;
      > > }
      > > inline void * data_type::getA ddress()[/color]
      >
      > inline void * data_type::getA ddress() const
      >[color=green]
      > > {
      > > return((void *)address);
      > > }
      > > inline void data_type::init _data_type()
      > > {
      > > address->a=1;
      > > address->b='a';
      > > address->c=1;
      > > };
      > >
      > > void foo(const data_type *);
      > >
      > > #define GET_ADDRESS(obj ect) ((object)->getAddress() )
      > >
      > > int main(int argc, char *argv[])
      > > {
      > > data_type temp_object;
      > > temp_object.ini t_data_type();
      > > foo(&temp_objec t);
      > > }
      > > void foo(const data_type *temp_object)
      > > {
      > > using namespace std;
      > >
      > > if (((TEMP_STRUCT *)(GET_ADDRESS( temp_object)))->a)
      > > cout << "Test Passed";
      > > //Error error: passing `const
      > > //data_type' as `this' argument of `void* data_type::getA ddress
      > > //()' discards qualifiers
      > > }[/color]
      >
      > Look up 'const member function'.
      >
      > -Mike[/color]

      Comment

      • Thomas Matthews

        #4
        Re: Const Qualifier question

        Thanks,
        read.
        is difficult to
        top-post, it
        Please.

        Append your replies to the end or intersperse.

        Mahesh Tomar wrote:
        [Re-arranged][color=blue]
        > "Mike Wahler" <mkwahler@mkwah ler.net> wrote in message news:<1JmZc.467 2$w%6.1531@news read1.news.pas. earthlink.net>. ..
        >[color=green]
        >>"Mahesh Tomar" <tomar27@msn.co m> wrote in message
        >>news:4647d063 .0409010800.5cf 2b29d@posting.g oogle.com...
        >>
        >>See below.
        >>
        >>[color=darkred]
        >>>Dear Readers,
        >>> I am porting my existing C code to C++. In my existing code
        >>>there are numerous functions that has been defined with CONST
        >>>qualifier. For eg. foo(const DATA_TYPE *x); DATA_TYPE is some typedef
        >>>structure and offcourse x is a pointer to it. Needless to say my
        >>>intention for writing such functions in C was to protect the accident
        >>>write to x's content. So far so good. While porting to C++, I've mada
        >>>DATA_TYPE as class and I want to retain the sanity of existing C
        >>>function that has Const qualifier. However am having some trouble,
        >>>which is illustrated in the sample code below :
        >>>
        >>>#include <iostream>
        >>>typedef struct _temp {
        >>>int a;
        >>>char b;
        >>>short int c;
        >>>}TEMP_STRUCT ; // Define some temporary structure for illustration
        >>>purpose
        >>>
        >>>class data_type
        >>>{
        >>>public :
        >>>void *address;
        >>>data_type(vo id);
        >>>~data_type() ;
        >>>void init_data_type( );
        >>>void * getAddress() ;[/color]
        >>
        >>void *getAddress() const;
        >>
        >>[color=darkred]
        >>>};
        >>>
        >>>data_type::d ata_type()
        >>>{
        >>>address = new TEMP_STRUCT;
        >>>}
        >>>inline void * data_type::getA ddress()[/color]
        >>
        >>inline void * data_type::getA ddress() const
        >>
        >>[color=darkred]
        >>>{
        >>>return((vo id *)address);
        >>>}
        >>>inline void data_type::init _data_type()
        >>>{
        >>>address->a=1;
        >>>address->b='a';
        >>>address->c=1;
        >>>};
        >>>
        >>>void foo(const data_type *);
        >>>
        >>>#define GET_ADDRESS(obj ect) ((object)->getAddress() )
        >>>
        >>>int main(int argc, char *argv[])
        >>>{
        >>>data_type temp_object;
        >>>temp_object. init_data_type( );
        >>>foo(&temp_ob ject);
        >>>}
        >>>void foo(const data_type *temp_object)
        >>>{
        >>>using namespace std;
        >>>
        >>>if (((TEMP_STRUCT *)(GET_ADDRESS( temp_object)))->a)
        >>> cout << "Test Passed";
        >>>//Error error: passing `const
        >>>//data_type' as `this' argument of `void* data_type::getA ddress
        >>>//()' discards qualifiers
        >>>}[/color]
        >>
        >>Look up 'const member function'.
        >>
        >>-Mike[/color]
        >
        > Mike,
        > Thanks for your time. However, I too have mentioned the solution in
        > my original e-mail where I stated "if member function,get_ad dress, is
        > defined as " void * getAddress() const", the compiler error goes away,
        > however, const qualifier inside foo also looses its meaning i.e. you
        > can write to the content of data type."
        > Putting a const qualifier at the end of function will make the error
        > go away, however, if I do something like this
        > void foo(const data_type *temp_object)
        > {
        > using namespace std;
        >
        > // This statement below will modify the content of temp_object and
        > that is
        > // not the intention.
        > ((TEMP_STRUCT *)(GET_ADDRESS( temp_object)))->a = 2;
        > cout << ((TEMP_STRUCT *)(GET_ADDRESS( temp_object)))->a;
        > }
        > If you see above, the intent of foo () function which was suppose to
        > protect any accidental write to the content of temp_object is lost. In
        > short I want to maintain the sanity of such functions (that am porting
        > to C++).
        > Any insight into this will be really appreciated.
        >
        > Thanks,
        > Mahesh
        >[/color]

        Have a look at:


        See also section 18.11

        Also, do yourself a favor and get rid of the macro.
        const data_type *temp_object;
        ((TEMP_STRUCT *)(GET_ADDRESS( temp_object)))->a = 2;

        translates to:
        1. ((TEMP_STRUCT *) (temp_object->get_address()) )->a = 2;
        2. ((struct _temp *) (temp_object->get_address()) )->a = 2;

        The expression:
        (temp_object->get_address( ))
        returns a type of "void *", which you are casting to
        a type of "struct _temp *".

        As we look in the definition of class "data_type" above,
        we find in the constructor, that "address" is
        initialized as:
        address = new _temp; /* simplified */

        So, you have a casting circle:
        1. Member address in class "data_type" is set to a new "_temp".
        2. In function foo, the the address is fetched from
        an instance of "data_type" and casted to a type "_temp".

        Your program could be simplified by reducing the casts:
        void foo (_temp * const const_temp_poin ter)
        {
        if (const_temp_poi nter->a)
        {
        cout << "Test Passed." << endl;
        }
        }

        int main(void)
        {
        _temp temp_object;
        foo(&temp_objec t);
        }

        or:
        int main(void)
        {
        _temp * p_temp_object = new _temp;
        foo(p_temp_obje ct);
        }


        Did I miss something?
        Are you trying to create some kind of smart pointer class?
        {Smart pointers are also in the FAQ.}

        --
        Thomas Matthews

        C++ newsgroup welcome message:

        C++ Faq: http://www.parashift.com/c++-faq-lite
        C Faq: http://www.eskimo.com/~scs/c-faq/top.html
        alt.comp.lang.l earn.c-c++ faq:

        Other sites:
        http://www.josuttis.com -- C++ STL Library book

        Comment

        • Old Wolf

          #5
          Re: Const Qualifier question

          tomar27@msn.com (Mahesh Tomar) wrote:
          [color=blue]
          > class data_type
          > {
          > public :
          > void *address;
          > data_type(void) ;
          > ~data_type();
          > void init_data_type( );
          > void * getAddress() ;
          > };
          > In C functions like foo() were called with "const TEMP_STRUCT *"
          > argument therefore compiler took care of any accident write to its
          > content. However in C++ this argument is changed to a class, which
          > fetches the address to TEMP_STRUCT, however, I still want the class to
          > return the address in such a way that the content of address can't be
          > modified inside the function. However, above sample code doesn't work
          > because foo is called with const qualifier, therefore complier
          > complains, if I try to access any of its member function. However if
          > get_address is defined as " void * getAddress() const", the compiler
          > error goes away, however, const qualifier inside foo also looses its
          > meaning i.e. you can write to the content of data type.[/color]

          const void * getAddress() const;

          (as well as your existing one). Then const objects will call this
          one and return a const void *, and non-const objects will call
          the existing one.
          BTW using 'void *' is bad because of type safety issues, you
          should consider using a template:

          template<typena me T>
          class data_type
          {
          public:
          T *address;
          data_type(): address(new T) {}
          ~data_type() { delete address; }
          void init_data_type( );
          T * getAddress() { return address; }
          T const *getAddress() const { return address; }
          };

          Your init_data_type function would not have worked anyway
          (you can't dereference a pointer to void). So:

          data_type<TEMP_ STRUCT>::init_d ata_type()
          {
          address->a=1;
          address->b='a';
          address->c=1;
          }

          Comment

          Working...