Two proxy classes in main class

Discussion in 'C++' started by Nephi Immortal, Jan 29, 2011.

  1. I created two private proxy classes and I put them into one main
    class. I use two functions Low_Byte() and High_Byte() to modify main
    class’ data member through reference and Word() through pointer.
    C++ Compiler complied without any problems. If I declare constant,
    then C++ Compiler will give you an error message.
    How can I add const function? I struggle while I am trying to figure
    for couple hours.

    class _16_Bits {
    private:
    typedef unsigned int size;

    class _Low_Byte {
    public:
    _Low_Byte( size &byte ) : m_data( byte ) {}
    ~_Low_Byte() {}

    _Low_Byte &operator= ( const size &byte ) {
    m_data &= 0xFF00;
    m_data |= byte & 0xFF;
    return *this;
    }

    operator size () { return m_data & 0xFF; }
    operator size () const { return m_data & 0xFF; }

    private:
    size &m_data;
    };

    class _High_Byte {
    public:
    _High_Byte( size &byte ) : m_data( byte ) {}
    ~_High_Byte() {}

    _High_Byte &operator= ( const size &byte ) {
    m_data &= 0xFF;
    m_data |= ( byte & 0xFF ) << 8;
    return *this;
    }

    operator size () { return ( m_data >> 8 ) & 0xFF; }
    operator size () const { return ( m_data >> 8 ) & 0xFF; }

    private:
    size &m_data;
    };

    public:
    explicit _16_Bits( size word ) : m_data( word ) {}
    ~_16_Bits() {}

    _16_Bits &operator= ( size word ) {
    m_data = word & 0xFFFF;
    return *this;
    }

    _Low_Byte Low_Byte() { return _Low_Byte( m_data ); }
    _High_Byte High_Byte() { return _High_Byte( m_data ); }
    _16_Bits &Word() { return *this; }

    operator size () { return m_data; }
    operator size () const { return m_data; }

    private:
    size m_data;
    };



    int main () {
    _16_Bits W( 0x1234 );

    W.Low_Byte() = 0x5A;
    W.High_Byte() = 0x7C;

    unsigned int L = W.Low_Byte();
    unsigned int H = W.High_Byte();

    W.Word() = 0xABCD;
    unsigned int W2 = W;

    const _16_Bits V( 0x1234 );


    unsigned int L2 = V.Low_Byte(); // error
    unsigned int H2 = V.High_Byte(); // error

    unsigned int V2 = V;

    return 0;
    }
     
    Nephi Immortal, Jan 29, 2011
    #1
    1. Advertising

  2. Nephi Immortal Wrote:

    > I created two private proxy classes and I put them into one
    > main
    > class. I use two functions Low_Byte() and High_Byte() to modify
    > main
    > class’ data member through reference and Word() through
    > pointer.
    > C++ Compiler complied without any problems. If I declare
    > constant,
    > then C++ Compiler will give you an error
    > message.
    > How can I add const function? I struggle while I am trying to
    > figure
    > for couple hours.


    The clean solution is to create two additional (nested) helper-classes
    _16_Bits::_Low_Byte_const and _16_Bits::_High_Byte_const, which give
    read-only access to the data similar to the existing _16_Bits::_Low_Byte and
    _16_Bits::_High_Byte.

    Then you can declare the const functions as

    _Low_Byte_const Low_Byte() const { return _Low_Byte_const( m_data ); }
    _High_Byte_const High_Byte() const { return _High_Byte_const( m_data ); }


    Another option is to add the following constructors to _Low_Byte (and
    similar for _High_Byte):

    _Low_Byte( const size& byte) : m_data(const_cast<size&>(byte) {}

    Then you can declare the const functions as

    _Low_Byte const Low_Byte() const { return _Low_Byte( m_data ); }

    technically, the const_cast in the constructor can lead to UB, but by
    returning a const-qualified object, the UB is averted because it still
    remains impossible to modify a const object.

    <snip - code>

    Bart v Ingen Schenau
     
    Bart van Ingen Schenau, Jan 29, 2011
    #2
    1. Advertising

  3. On Jan 29, 6:18 am, Bart van Ingen Schenau <>
    wrote:
    > Nephi Immortal Wrote:
    >
    > >    I created two private proxy classes and I put them into one
    > > main
    > > class.  I use two functions Low_Byte() and High_Byte() to modify
    > > main
    > > class’ data member through reference and Word() through
    > > pointer.
    > >    C++ Compiler complied without any problems.  If I declare
    > > constant,
    > > then C++ Compiler will give you an error
    > > message.
    > >    How can I add const function?  I struggle while I am trying to
    > > figure
    > > for couple hours.

    >
    > The clean solution is to create two additional (nested) helper-classes
    > _16_Bits::_Low_Byte_const and _16_Bits::_High_Byte_const, which give
    > read-only access to the data similar to the existing _16_Bits::_Low_Byte and
    > _16_Bits::_High_Byte.
    >
    > Then you can declare the const functions as
    >
    >   _Low_Byte_const Low_Byte() const { return _Low_Byte_const( m_data ); }
    >   _High_Byte_const High_Byte() const { return _High_Byte_const( m_data ); }
    >
    > Another option is to add the following constructors to _Low_Byte (and
    > similar for _High_Byte):
    >
    >   _Low_Byte( const size& byte) : m_data(const_cast<size&>(byte) {}
    >
    > Then you can declare the const functions as
    >
    >   _Low_Byte const Low_Byte() const { return _Low_Byte( m_data ); }
    >
    > technically, the const_cast in the constructor can lead to UB, but by
    > returning a const-qualified object, the UB is averted because it still
    > remains impossible to modify a const object.


    You suggested two non-constant class helpers and other two constant
    class helpers into one main class. It is the only best option to
    avoid constness_cast keyword due to undefined behavior.
    I use the option as you suggested. However, Low_Byte_Const class has
    operator=. C++ Compiler will compile without any problems since
    m_data is supposed to be read-only. How can C++ Compiler reports an
    error as saying left value is declared constant rather than cannot
    access to private operator=?
    Perhaps, you suggest to use private keyword and do not worry the non-
    message as saying constant left value.

    class _Low_Byte_Const {
    public:
    _Low_Byte_Const( const size &byte ) : m_data( byte ) {}
    ~_Low_Byte_Const() {}

    _Low_Byte_Const &operator= ( const _Low_Byte_Const &right ) {
    // size temp_data = right.m_data;
    return *this; }

    // operator size () { return m_data & 0xFF; }
    operator size () const { return m_data & 0xFF; }

    //private: /* supoose to be uncommented */
    _Low_Byte_Const &operator= ( const size &byte ) {
    byte; // ignore level 4 warning
    // m_data &= 0xFF00;
    // m_data |= byte & 0xFF;
    return *this;
    }

    private:
    const size m_data;
    };

    Do I need to declare reference ‘&’ between ‘const size’ and ‘byte’ in
    operator= since it is only one value. The error message will report
    as saying cannot convert from size & to size because the value may be
    non-reference.

    Example:

    size value = 0x7A;
    w.Low_Byte() = 0x4C; // pass by copy value
    w.Low_Byte() = value; // pass by reference

    The main class can be either non-constant or constant. If I choose
    to declare constant, am I required to create two copies of member
    functions on each pair of member functions.

    For example:
    void Print_Hex() { /* your code */ }
    void Print_Hex() const { /* your code */ }

    void Print_Dec() { /* your code */ }
    void Print_Dec() const { /* your code */ }

    void Print_Bin() { /* your code */ }
    void Print_Bin() const { /* your code */ }

    etc….

    The same code in function body can waste source code’s space because
    of twice duplication. Perhaps, you suggest – declare and define
    global function as Print_String() before class definition and then
    pair of Print_Hex(), Print_Dec(), and Print_Bin() are either non-
    constant or constant will call non-constant global function
    Print_String().
     
    Nephi Immortal, Jan 29, 2011
    #3
  4. Nephi Immortal Wrote:

    > On Jan 29, 6:18 am, Bart van Ingen Schenau
    > <> wrote:
    > > Nephi Immortal Wrote:
    > >
    > > >    I created two private proxy classes and I put them into one
    > > > main
    > > > class.  I use two functions Low_Byte() and High_Byte() to modify
    > > > main
    > > > class’ data member through reference and Word()

    > through pointer.
    > > >    C++ Compiler complied without any problems.  If I

    > declare constant,
    > > > then C++ Compiler will give you an

    > error message.
    > > >    How can I add const function?  I struggle while I am trying

    > to figure for couple hours.
    > >
    > > The clean solution is to create two additional (nested)

    > helper-classes
    > > _16_Bits::_Low_Byte_const and _16_Bits::_High_Byte_const, which

    > give
    > > read-only access to the data similar to the existing _16_Bits::_Low_Byte

    > and
    > >

    > _16_Bits::_High_Byte.
    > >
    > > Then you can declare the const functions

    > as
    > >
    > >   _Low_Byte_const Low_Byte() const { return _Low_Byte_const( m_data );

    > }
    > >   _High_Byte_const High_Byte() const { return _High_Byte_const( m_data

    > );
    > }
    > >
    > > Another option is to add the following constructors to _Low_Byte

    > (and
    > > similar for

    > _High_Byte):
    > >
    > >   _Low_Byte( const size& byte) : m_data(const_cast<size&>(byte)

    > {}
    > >
    > > Then you can declare the const functions

    > as
    > >
    > >   _Low_Byte const Low_Byte() const { return _Low_Byte( m_data );

    > }
    > >
    > > technically, the const_cast in the constructor can lead to UB, but

    > by
    > > returning a const-qualified object, the UB is averted because it

    > still
    > > remains impossible to modify a const

    > object.
    >
    > You suggested two non-constant class helpers and other two
    > constant
    > class helpers into one main class. It is the only best option
    > to
    > avoid constness_cast keyword due to undefined
    > behavior.
    > I use the option as you suggested. However, Low_Byte_Const class
    > has operator=.


    Why? What good is it to declare an operator= on a class that is not supposed
    to support assignment?

    > C++ Compiler will compile without any problems since
    > m_data is supposed to be read-only. How can C++ Compiler reports
    > an
    > error as saying left value is declared constant rather than
    > cannot
    > access to private
    > operator=?
    > Perhaps, you suggest to use private keyword and do not worry the
    > non-
    > message as saying constant left
    > value.
    >
    > class _Low_Byte_Const
    > {
    > public:
    > _Low_Byte_Const( const size &byte ) : m_data( byte )
    > {}
    > ~_Low_Byte_Const()
    > {}
    >
    > _Low_Byte_Const &operator= ( const _Low_Byte_Const &right )
    > {
    > // size temp_data =
    > right.m_data;
    > return *this;
    > }

    This operator= should be left out completely. As _Low_Byte_Const has a
    reference-type member (m_data), the compiler will not be able to generate an
    operator= and that is exactly the behaviour you want.

    >
    > // operator size () { return m_data & 0xFF;
    > }
    > operator size () const { return m_data & 0xFF;
    > }
    >
    > //private: /* supoose to be uncommented
    > */
    > _Low_Byte_Const &operator= ( const size &byte )
    > {
    > byte; // ignore level 4
    > warning
    > // m_data &=
    > 0xFF00;
    > // m_data |= byte &
    > 0xFF;
    > return
    > *this;
    >
    > }

    This operator= should be left out as well. You don't want to support
    assignment of an integer, so you should not provide any operators that would
    be used in such an assignment.

    >
    > private:
    > const size
    > m_data;
    > };
    >

    <snip>
    > The main class can be either non-constant or constant. If I
    > choose
    > to declare constant, am I required to create two copies of
    > member
    > functions on each pair of member
    > functions.


    No. If the function itself does not modify *this and is also does not pass
    pointers or references to other functions that might cause modification of
    *this, then it is sufficient to have only one, const-qualified, function.
    This function can be used both by const and non-const objects.

    Bart v Ingen Schenau
     
    Bart van Ingen Schenau, Jan 30, 2011
    #4
    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. John M
    Replies:
    1
    Views:
    1,213
    Kumar Reddi
    May 29, 2005
  2. cyril
    Replies:
    2
    Views:
    3,878
    cyril
    Aug 25, 2004
  3. Hal Styli
    Replies:
    14
    Views:
    1,657
    Old Wolf
    Jan 20, 2004
  4. Frederick Ding

    int main() or int main(void)?

    Frederick Ding, Dec 3, 2005, in forum: C Programming
    Replies:
    10
    Views:
    660
  5. Ravi
    Replies:
    17
    Views:
    933
    Kenneth Brody
    Apr 1, 2006
Loading...

Share This Page