Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Two proxy classes in main class

Reply
Thread Tools

Two proxy classes in main class

 
 
Nephi Immortal
Guest
Posts: n/a
 
      01-29-2011
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;
}
 
Reply With Quote
 
 
 
 
Bart van Ingen Schenau
Guest
Posts: n/a
 
      01-29-2011
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

 
Reply With Quote
 
 
 
 
Nephi Immortal
Guest
Posts: n/a
 
      01-29-2011
On Jan 29, 6:18*am, Bart van Ingen Schenau <(E-Mail Removed)>
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().
 
Reply With Quote
 
Bart van Ingen Schenau
Guest
Posts: n/a
 
      01-30-2011
Nephi Immortal Wrote:

> On Jan 29, 6:18*am, Bart van Ingen Schenau
> <(E-Mail Removed)> 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

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Nested Class, Member Class, Inner Class, Local Class, Anonymous Class E11 Java 1 10-12-2005 03:34 PM
adding main.aspx.vb & main.aspx.resx under aspx John M ASP .Net 1 05-29-2005 09:27 PM
instanciate a class in a jar file with class.forname, while my main class is in another jar cyril Java 2 08-25-2004 06:55 AM
int main(int argc, char *argv[] ) vs int main(int argc, char **argv ) Hal Styli C Programming 14 01-20-2004 10:00 PM



Advertisments