Overloading Operator[] through 'this' pointer?

I

Immortal Nephi

Can overloading operator[] be connected to any member functions
through ‘this’ pointer? I do not want to insert assignment between
array object and integer value. I prefer to place integer value in
the member function’s parameter.


For example:

class Array
{
public:
Array( int size ) : pData( new unsigned char[ size ] )
{}

~Array()
{
delete [] pData;
}

int &operator[]( int index )
{
return pData[ index ];
}

Array &Set_LowNibble( unsigned char val, int index )
{
pData[ index ] &= 0xF0;
pData[ index ] |= (val & 0x0F );
return *this;
}

Array &Set_HighNibble( unsigned char val, int index )
{
pData[ index ] &= 0x0F;

unsigned char temp = val;
temp &= 0x0F;
temp <<= 4;

pData[ index ] |= temp;

return *this;
}

private:
unsigned char *pData;
};

int main()
{
Array array( 4 );

array[ 0 ] = 0x1E; // Always valid code

// Not valid code but you find another way
array[ 1 ].Set_LowNibble( 0x0D, 1 ).Set_HighNibble( 0x02, 1 );

return 0;
}
 
K

Kai-Uwe Bux

Immortal said:
Can overloading operator[] be connected to any member functions
through ?this? pointer?

It's not entirely clear, what you mean; but the answer probably is "no".
I do not want to insert assignment between
array object and integer value. I prefer to place integer value in
the member function?s parameter.


For example:

class Array
{
public:
Array( int size ) : pData( new unsigned char[ size ] )
{}

~Array()
{
delete [] pData;
}

int &operator[]( int index )
{
return pData[ index ];
}

Array &Set_LowNibble( unsigned char val, int index )
{
pData[ index ] &= 0xF0;
pData[ index ] |= (val & 0x0F );
return *this;
}

Array &Set_HighNibble( unsigned char val, int index )
{
pData[ index ] &= 0x0F;

unsigned char temp = val;
temp &= 0x0F;
temp <<= 4;

pData[ index ] |= temp;

return *this;
}

private:
unsigned char *pData;
};

int main()
{
Array array( 4 );

array[ 0 ] = 0x1E; // Always valid code

// Not valid code but you find another way
array[ 1 ].Set_LowNibble( 0x0D, 1 ).Set_HighNibble( 0x02, 1 );

Would this line differ in any observable way from:

array[ 0 ].Set_LowNibble( 0x0D, 1 ).Set_HighNibble( 0x02, 1 )

It appears that the Set_LowNibble() and Set_HighNibble() methods already
provide index arguments. Hence, why not:

array.Set_LowNibble( 0x0D, 1 ).Set_HighNibble( 0x02, 1 )

which, I think, should work.
return 0;
}


Best

Kai-Uwe Bux
 
I

Immortal Nephi

Immortal said:
Can overloading operator[] be connected to any member functions
through ?this? pointer?

It's not entirely clear, what you mean; but the answer probably is "no".




I do not want to insert assignment between
array object and integer value.  I prefer to place integer value in
the member function?s parameter.
For example:
class Array
{
public:
Array( int size ) : pData( new unsigned char[ size ] )
{}
~Array()
{
delete [] pData;
}
int &operator[]( int index )
{
return pData[ index ];
}
Array &Set_LowNibble( unsigned char val, int index )
{
pData[ index ] &= 0xF0;
pData[ index ] |= (val & 0x0F );
return *this;
}
Array &Set_HighNibble( unsigned char val, int index )
{
pData[ index ] &= 0x0F;
unsigned char temp = val;
temp &= 0x0F;
temp <<= 4;
pData[ index ] |= temp;
return *this;
}
private:
unsigned char *pData;
};
int main()
{
Array array( 4 );
array[ 0 ] = 0x1E; // Always valid code
// Not valid code but you find another way
array[ 1 ].Set_LowNibble( 0x0D, 1 ).Set_HighNibble( 0x02, 1 );

Would this line differ in any observable way from:

  array[ 0 ].Set_LowNibble( 0x0D, 1 ).Set_HighNibble( 0x02, 1 )

It appears that the Set_LowNibble() and Set_HighNibble() methods already
provide index arguments. Hence, why not:

  array.Set_LowNibble( 0x0D, 1 ).Set_HighNibble( 0x02, 1 )

You are right that it does not work like this.

array[ 0 ].Set_LowNibble( 0x0D, 1 ).Set_HighNibble( 0x02, 1 )

If change to

array[ 2 ].Set_LowNibble( 0x0D ).Set_HighNibble( 0x02 )

index is removed from function paramater. Create one array object.
Then one array object create unsigned char arrays. Use operator[] to
assign value to either Set_LowNibble or Set_HighNibble functions.

You say the answer no does not work. Right?
 
K

Kai-Uwe Bux

Immortal said:
Immortal said:
Can overloading operator[] be connected to any member functions
through ?this? pointer?

It's not entirely clear, what you mean; but the answer probably is "no".




I do not want to insert assignment between
array object and integer value. I prefer to place integer value in
the member function?s parameter.
For example:
class Array
{
public:
Array( int size ) : pData( new unsigned char[ size ] )
{}
~Array()
{
delete [] pData;
}
int &operator[]( int index )
{
return pData[ index ];
}
Array &Set_LowNibble( unsigned char val, int index )
{
pData[ index ] &= 0xF0;
pData[ index ] |= (val & 0x0F );
return *this;
}
Array &Set_HighNibble( unsigned char val, int index )
{
pData[ index ] &= 0x0F;
unsigned char temp = val;
temp &= 0x0F;
temp <<= 4;
pData[ index ] |= temp;
return *this;
}
private:
unsigned char *pData;
};
int main()
{
Array array( 4 );
array[ 0 ] = 0x1E; // Always valid code
// Not valid code but you find another way
array[ 1 ].Set_LowNibble( 0x0D, 1 ).Set_HighNibble( 0x02, 1 );

Would this line differ in any observable way from:

array[ 0 ].Set_LowNibble( 0x0D, 1 ).Set_HighNibble( 0x02, 1 )

It appears that the Set_LowNibble() and Set_HighNibble() methods already
provide index arguments. Hence, why not:

array.Set_LowNibble( 0x0D, 1 ).Set_HighNibble( 0x02, 1 )

You are right that it does not work like this.

array[ 0 ].Set_LowNibble( 0x0D, 1 ).Set_HighNibble( 0x02, 1 )

If change to

array[ 2 ].Set_LowNibble( 0x0D ).Set_HighNibble( 0x02 )

index is removed from function paramater. Create one array object.
Then one array object create unsigned char arrays. Use operator[] to
assign value to either Set_LowNibble or Set_HighNibble functions.

You say the answer no does not work. Right?

Well, if you _really_ want that syntax to work, you _could_ define
operator[] to return a proxy class. These proxy objects would convert to
int& to support direct assignment but also provide Set_LowNibble() and
Set_HighNibble() methods. However, as with all proxy classes and implicit
conversions, you have to watch out for possible surprises.


Best

Kai-Uwe Bux
 
P

Paul Bibbings

Immortal Nephi said:
Can overloading operator[] be connected to any member functions
through ¡®this¡¯ pointer? I do not want to insert assignment between
array object and integer value. I prefer to place integer value in
the member function¡¯s parameter.


For example:

class Array
{
public:
Array( int size ) : pData( new unsigned char[ size ] )
{}

~Array()
{
delete [] pData;
}

int &operator[]( int index )
{
return pData[ index ];
}

Array &Set_LowNibble( unsigned char val, int index )
{
pData[ index ] &= 0xF0;
pData[ index ] |= (val & 0x0F );
return *this;
}

Array &Set_HighNibble( unsigned char val, int index )
{
pData[ index ] &= 0x0F;

unsigned char temp = val;
temp &= 0x0F;
temp <<= 4;

pData[ index ] |= temp;

return *this;
}

private:
unsigned char *pData;
};

int main()
{
Array array( 4 );

array[ 0 ] = 0x1E; // Always valid code

// Not valid code but you find another way
array[ 1 ].Set_LowNibble( 0x0D, 1 ).Set_HighNibble( 0x02, 1 );

return 0;
}

The following is just an idea to think about. I have not given very
much consideration to the details and I am not completely sure why you
are wanting it to work in this way.

class Byte
{
public:
Byte(unsigned char& c) : c_(c) { }
Byte& operator=(unsigned char val)
{
c_ = val;
return *this;
}
Byte& Set_LowNibble(unsigned char val)
{
c_ &= 0xF0;
c_ |= (val & 0x0F);
return *this;
}
Byte& Set_HighNibble(unsigned char val)
{
c_ &= 0x0F;
unsigned char temp = val;
temp &= 0x0F;
temp <<= 4;
c_ |= temp;
return *this;
}
operator unsigned char&() { return c_; }
private:
unsigned char& c_;
};

class Array
{
public:
Array(int size)
: pData(new unsigned char[size])
{ }
~Array()
{
delete [] pData;
}
Byte operator[](int index)
{
return pData[index];
}
private:
unsigned char *pData;
};

int main()
{
Array array(4);

array[0] = 0x3C;

array[1].Set_LowNibble(0x0D).Set_HighNibble(0x02);

std::cout << array[0] << '\n';
std::cout << array[1] << '\n';

unsigned char& c_ref = array[1];
c_ref = array[0];

std::cout << array[0] << '\n';
std::cout << array[1] << '\n';

return 0;
}

/**
* Output:
* <
* -
* <
* <
*/

Regards

Paul Bibbings
 
I

Immortal Nephi

Immortal Nephi said:
   Can overloading operator[] be connected to any member functions
through ‘this’ pointer?  I do not want to insert assignment between
array object and integer value.  I prefer to place integer value in
the member function’s parameter.
For example:
class Array
{
public:
   Array( int size ) : pData( new unsigned char[ size ] )
   {}
   ~Array()
   {
           delete [] pData;
   }
   int &operator[]( int index )
   {
           return pData[ index ];
   }
   Array &Set_LowNibble( unsigned char val, int index )
   {
           pData[ index ] &= 0xF0;
           pData[ index ] |= (val & 0x0F );
           return *this;
   }
   Array &Set_HighNibble( unsigned char val, int index )
   {
           pData[ index ] &= 0x0F;
           unsigned char temp = val;
           temp &= 0x0F;
           temp <<= 4;
           pData[ index ] |= temp;
           return *this;
   }
private:
   unsigned char *pData;
};
int main()
{
   Array array( 4 );
   array[ 0 ] = 0x1E; // Always valid code
   // Not valid code but you find another way
   array[ 1 ].Set_LowNibble( 0x0D, 1 ).Set_HighNibble( 0x02, 1 );
   return 0;
}

The following is just an idea to think about.  I have not given very
much consideration to the details and I am not completely sure why you
are wanting it to work in this way.

   class Byte
   {
   public:
      Byte(unsigned char& c) : c_(c) { }
      Byte& operator=(unsigned char val)
      {
         c_ = val;
         return *this;
      }
      Byte& Set_LowNibble(unsigned char val)
      {
         c_ &= 0xF0;
         c_ |= (val & 0x0F);
         return *this;
      }
      Byte& Set_HighNibble(unsigned char val)
      {
         c_ &= 0x0F;
         unsigned char temp = val;
         temp &= 0x0F;
         temp <<= 4;
         c_ |= temp;
         return *this;
      }
      operator unsigned char&() { return c_; }
   private:
      unsigned char& c_;
   };

   class Array
   {
   public:
      Array(int size)
         : pData(new unsigned char[size])
      { }
      ~Array()
      {
         delete [] pData;
      }
      Byte operator[](int index)
      {
         return pData[index];
      }
   private:
      unsigned char *pData;
   };

   int main()
   {
      Array array(4);

      array[0] = 0x3C;

      array[1].Set_LowNibble(0x0D).Set_HighNibble(0x02);

      std::cout << array[0] << '\n';
      std::cout << array[1] << '\n';

      unsigned char& c_ref = array[1];
      c_ref = array[0];

      std::cout << array[0] << '\n';
      std::cout << array[1] << '\n';

      return 0;
   }

   /**
    * Output:
    *    <
    *    -
    *    <
    *    <
    */

That code looks great. One problem—If I want to create a pointer,
Set_LowNibble and Set_HighNibble are not members of that class.

Array *pArray = new Array( 4 );

What is another way to fix?
 
P

Paul Bibbings

Immortal Nephi said:
Immortal Nephi said:
Can overloading operator[] be connected to any member functions
through ‘this’ pointer? I do not want to insert assignment between
array object and integer value. I prefer to place integer value in
the member function’s parameter.
For example:
class Array
{
public:
Array( int size ) : pData( new unsigned char[ size ] )
{}
~Array()
{
delete [] pData;
}
int &operator[]( int index )
{
return pData[ index ];
}
Array &Set_LowNibble( unsigned char val, int index )
{
pData[ index ] &= 0xF0;
pData[ index ] |= (val & 0x0F );
return *this;
}
Array &Set_HighNibble( unsigned char val, int index )
{
pData[ index ] &= 0x0F;
unsigned char temp = val;
temp &= 0x0F;
temp <<= 4;
pData[ index ] |= temp;
return *this;
}
private:
unsigned char *pData;
};
int main()
{
Array array( 4 );
array[ 0 ] = 0x1E; // Always valid code
// Not valid code but you find another way
array[ 1 ].Set_LowNibble( 0x0D, 1 ).Set_HighNibble( 0x02, 1 );
return 0;
}

The following is just an idea to think about. I have not given very
much consideration to the details and I am not completely sure why you
are wanting it to work in this way.

class Byte
{
public:
Byte(unsigned char& c) : c_(c) { }
Byte& operator=(unsigned char val)
{
c_ = val;
return *this;
}
Byte& Set_LowNibble(unsigned char val)
{
c_ &= 0xF0;
c_ |= (val & 0x0F);
return *this;
}
Byte& Set_HighNibble(unsigned char val)
{
c_ &= 0x0F;
unsigned char temp = val;
temp &= 0x0F;
temp <<= 4;
c_ |= temp;
return *this;
}
operator unsigned char&() { return c_; }
private:
unsigned char& c_;
};

class Array
{
public:
Array(int size)
: pData(new unsigned char[size])
{ }
~Array()
{
delete [] pData;
}
Byte operator[](int index)
{
return pData[index];
}
private:
unsigned char *pData;
};

int main()
{
Array array(4);

array[0] = 0x3C;

array[1].Set_LowNibble(0x0D).Set_HighNibble(0x02);

std::cout << array[0] << '\n';
std::cout << array[1] << '\n';

unsigned char& c_ref = array[1];
c_ref = array[0];

std::cout << array[0] << '\n';
std::cout << array[1] << '\n';

return 0;
}

/**
* Output:
* <
* -
* <
* <
*/

That code looks great. One problem—If I want to create a pointer,
Set_LowNibble and Set_HighNibble are not members of that class.

I don't understand the logic in *wanting* Set_LowNibble and
Set_HighNibble to be members of your Array class. Your Array is a
container of elements where the concept of high and low nibbles applies
to the *elements* and not to the container as a whole. I can't
visualize what setting a high or low nibble *of a container* would mean,
conceptually, as opposed to doing the same to any one of its elements.
In the example code above an element is modelled by the proxy Byte,
for which the operation of `setting the high/low nibble' *makes sense*.
Array *pArray = new Array( 4 );

What is another way to fix?

In this example, using a pointer, what would be wrong with:

(*arr_ptr)[0] = 0x3C;
(*arr_ptr)[1].Set_LowNibble(0x0D).Set_HighNibble(0x02);
// etc.

Regards

Paul Bibbings
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,073
Latest member
DarinCeden

Latest Threads

Top