Unanticipated behavior from overloaded cast operator... [modified]
-
The code:
class testClass {
public:
testClass() { m_buff = new BYTE[20];
memcpy(m_buff, "0123456789", 10);
};
~testClass() { delete m_buff; };operator LPBYTE () { return m\_buff; }; void show() { cout << "m\_buff = " << (\_\_int64) (void \*) m\_buff << "\\n\\t"; // Show address of m\_buff for (int i = 0; i < 10; i++) // Show contents of m\_buff cout << m\_buff\[i\]; cout << "\\n"; };
private:
LPBYTE m_buff;
};int main(int argc, char * argv[])
{
testClass * foo = new testClass();
foo->show();
cout << "foo = " << (__int64) (void *) foo << "\n"; // Show address of foo
cout << "(LPBYTE) foo = " << (__int64) (void *) ( (LPBYTE) foo ) << "\n\t"; // Show address of cast (LPBYTE) foo
for (int i = 0; i < 10; i++) // Show contents of cast (LPBYTE) foo
cout << ((LPBYTE) foo)[i];cout << "\\n"; delete foo; return true;
};
And some output:
m_buff = 9180016
0123456789
foo = 9179968
(LPBYTE) foo = 9179968
-garbage-I was expecting to see:
m_buff = 9180016
0123456789
foo = 9179968
(LPBYTE) foo = 9180016 // same address as m_buff
0123456789What am I missing ? I know I could accomplish something similar with a member function returning the address of
m_buff
, but in my ever more ridiculous quest to learn more aspects of C++, I wanted to try this operator overloading bit.... As always, any guidance you can offer is greatly appreciated. MZRmodified on Wednesday, March 17, 2010 5:11 AMP.S. My apologies for using
__int64
... I know it's Microsoft specific, but I use what I've got.u expect to see
(LPBYTE) foo = 9180016 // same address as m_buff
and its true.. remeber m_buff is a ptr, so just check its address (using &m_buff). Hope u will see it is same as (LPBYTE)foo :) Means m_buff is just a ptr which holds an address somewhere in heap. And while printing (LPBYTE)foo it provides garbage, because both foo & m_buff is dynamically allocated, so we can never say where they r in heap. To become more clear make m_buff an array, say m_buff[10], then (LPBYTE)foo will print 0123.. as u expected. Also see (void*)&m_buff = (void*)foo :) Hope now things are clear to u..
-
The code:
class testClass {
public:
testClass() { m_buff = new BYTE[20];
memcpy(m_buff, "0123456789", 10);
};
~testClass() { delete m_buff; };operator LPBYTE () { return m\_buff; }; void show() { cout << "m\_buff = " << (\_\_int64) (void \*) m\_buff << "\\n\\t"; // Show address of m\_buff for (int i = 0; i < 10; i++) // Show contents of m\_buff cout << m\_buff\[i\]; cout << "\\n"; };
private:
LPBYTE m_buff;
};int main(int argc, char * argv[])
{
testClass * foo = new testClass();
foo->show();
cout << "foo = " << (__int64) (void *) foo << "\n"; // Show address of foo
cout << "(LPBYTE) foo = " << (__int64) (void *) ( (LPBYTE) foo ) << "\n\t"; // Show address of cast (LPBYTE) foo
for (int i = 0; i < 10; i++) // Show contents of cast (LPBYTE) foo
cout << ((LPBYTE) foo)[i];cout << "\\n"; delete foo; return true;
};
And some output:
m_buff = 9180016
0123456789
foo = 9179968
(LPBYTE) foo = 9179968
-garbage-I was expecting to see:
m_buff = 9180016
0123456789
foo = 9179968
(LPBYTE) foo = 9180016 // same address as m_buff
0123456789What am I missing ? I know I could accomplish something similar with a member function returning the address of
m_buff
, but in my ever more ridiculous quest to learn more aspects of C++, I wanted to try this operator overloading bit.... As always, any guidance you can offer is greatly appreciated. MZRmodified on Wednesday, March 17, 2010 5:11 AMP.S. My apologies for using
__int64
... I know it's Microsoft specific, but I use what I've got.As Moak said, try :) :
cout << foo->LPBYTE()[0]; // is the garbage here ? :)
virtual void BeHappy() = 0;
-
Mike the Red wrote:
I was expecting to see:
Mike the Red wrote:
m_buff = 9180016 0123456789 foo = 9179968 (LPBYTE) foo = 9180016 // same address as m_buff 0123456789
Mike the Red wrote:
What am I missing ?
The address of the class and the one of the
m_buff
variable (i.e.**&**m_buff
) are the same. On the other hand, the address of the class differs from that of the memory buffer (i.e.m_buff
). To verify, add the following line to the show method:cout << "&m_buff = " << (__int64) (void *) &m_buff << "\n\t"; // Show the REAL address of m_buff
(that happens because of dynamic memory allocation). :)
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
[My articles]I changed the operator function to:
operator LPBYTE () { cout << "Inside operator.\n"; return &this->m_buff[0]; };
...but
Inside operator.
never appears in the output. If I explicitly usefoo->operator LPBYTE()
thenInside operator.
appears in the output but not if I use an explicit cast(LPBYTE) foo
. Any ideas on that one ? Thanks, MZR -
As Moak said, try :) :
cout << foo->LPBYTE()[0]; // is the garbage here ? :)
virtual void BeHappy() = 0;
This:
LPBYTE bar = foo->operator LPBYTE();
for (int i = 0; i < 10; i++)
cout << bar[i];
cout << "\n";Gives the expected output
0123456789
....it's like my overloaded operator isn't being called when I try to explicitly cast to
(LPBYTE)
. -
This:
LPBYTE bar = foo->operator LPBYTE();
for (int i = 0; i < 10; i++)
cout << bar[i];
cout << "\n";Gives the expected output
0123456789
....it's like my overloaded operator isn't being called when I try to explicitly cast to
(LPBYTE)
.Very good :) And now, as Moak said, try :) :
LPBYTE lpOut = *foo;
cout << lpOut[0]; // is the garbage here ? :)virtual void BeHappy() = 0;
-
I changed the operator function to:
operator LPBYTE () { cout << "Inside operator.\n"; return &this->m_buff[0]; };
...but
Inside operator.
never appears in the output. If I explicitly usefoo->operator LPBYTE()
thenInside operator.
appears in the output but not if I use an explicit cast(LPBYTE) foo
. Any ideas on that one ? Thanks, MZRSorry, I misunderstood the original question (I missed the cast operator overloading... :-O ). You overloaded correctly it, but you should apply it to an instance of the class not to a pointer to, modify from
for (int i = 0; i < 10; i++) // Show contents of cast (LPBYTE) foo
cout << ((LPBYTE) foo)[i];to
for (int i = 0; i < 10; i++) // Show contents of cast (LPBYTE) foo
cout << ((LPBYTE) (*foo))[i];:)
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
[My articles] -
u expect to see
(LPBYTE) foo = 9180016 // same address as m_buff
and its true.. remeber m_buff is a ptr, so just check its address (using &m_buff). Hope u will see it is same as (LPBYTE)foo :) Means m_buff is just a ptr which holds an address somewhere in heap. And while printing (LPBYTE)foo it provides garbage, because both foo & m_buff is dynamically allocated, so we can never say where they r in heap. To become more clear make m_buff an array, say m_buff[10], then (LPBYTE)foo will print 0123.. as u expected. Also see (void*)&m_buff = (void*)foo :) Hope now things are clear to u..
I'm clear that
m_buff
is a pointer, and what I want is for(LPBYTE) foo
to point to the same placem_buff
points, not to point tom_buff
itself. My class uses the buffer size to sometimes havem_buff
point to a dynamically allocatedBYTE
array and sometimes point to a MMF, but to allow the given buffer to be accessed as an LPBYTE regardless of the buffer 'implementation.' It seems, though, that(LPBYTE) foo
gives a pointer to thetestClass
object, rather than the memory pointed to bym_buff
. I think I said it in the original post, but I could accomplish this easily with a member function likeLPBYTE getBuff() { return &this->m_buff[0]; };
..but I thought this was a good opportunity to learn about operator overloading. Thanks! MZR
-
Sorry, I misunderstood the original question (I missed the cast operator overloading... :-O ). You overloaded correctly it, but you should apply it to an instance of the class not to a pointer to, modify from
for (int i = 0; i < 10; i++) // Show contents of cast (LPBYTE) foo
cout << ((LPBYTE) foo)[i];to
for (int i = 0; i < 10; i++) // Show contents of cast (LPBYTE) foo
cout << ((LPBYTE) (*foo))[i];:)
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
[My articles]-nt-
-
Mike the Red wrote:
operator LPBYTE () { return m_buff; };
Don't you mean
(LPBYTE)*foo
since foo is a pointer? /Moak PS: You might want to add copy constructor and assignment operator to your class. Law of the Big Two, classes that handle memory/resources usually need a copy constructor and an assignment operator.Webchat in Europe :java: (only 4K)
I didn't understand your post until Pallini gave a longer explanation of this. Thanks for your help!!! PS: Thanks for the suggestion about the Big Two, but I don't think so in this case. The idea behind the class is for it to always behave as a dynamically-allocated
LPBYTE
, but somtimes point to a MMF, when the buffer is larger than a certain threshold. In both cases (trueLPBYTE
orLPBYTE
pointing to an MMF), the standard memory functions (memcpy
,memset
, etc.) are appropriate. (Which is why I want the cast to point to the same place as the member pointerm_buff
.) -
-nt-
You are welcome. :)
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
[My articles] -
I didn't understand your post until Pallini gave a longer explanation of this. Thanks for your help!!! PS: Thanks for the suggestion about the Big Two, but I don't think so in this case. The idea behind the class is for it to always behave as a dynamically-allocated
LPBYTE
, but somtimes point to a MMF, when the buffer is larger than a certain threshold. In both cases (trueLPBYTE
orLPBYTE
pointing to an MMF), the standard memory functions (memcpy
,memset
, etc.) are appropriate. (Which is why I want the cast to point to the same place as the member pointerm_buff
.)