Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Unanticipated behavior from overloaded cast operator... [modified]

Unanticipated behavior from overloaded cast operator... [modified]

Scheduled Pinned Locked Moved C / C++ / MFC
c++question
14 Posts 5 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Mike the Red

    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
    0123456789

    What 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. MZR

    modified 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.

    C Offline
    C Offline
    Cool_Dev
    wrote on last edited by
    #4

    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..

    M 1 Reply Last reply
    0
    • M Mike the Red

      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
      0123456789

      What 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. MZR

      modified 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.

      E Offline
      E Offline
      Eugen Podsypalnikov
      wrote on last edited by
      #5

      As Moak said, try :) :

      cout << foo->LPBYTE()[0]; // is the garbage here ? :)

      virtual void BeHappy() = 0;

      M 1 Reply Last reply
      0
      • CPalliniC CPallini

        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]

        M Offline
        M Offline
        Mike the Red
        wrote on last edited by
        #6

        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 use foo->operator LPBYTE() then Inside operator. appears in the output but not if I use an explicit cast (LPBYTE) foo. Any ideas on that one ? Thanks, MZR

        CPalliniC 1 Reply Last reply
        0
        • E Eugen Podsypalnikov

          As Moak said, try :) :

          cout << foo->LPBYTE()[0]; // is the garbage here ? :)

          virtual void BeHappy() = 0;

          M Offline
          M Offline
          Mike the Red
          wrote on last edited by
          #7

          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).

          E 1 Reply Last reply
          0
          • M Mike the Red

            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).

            E Offline
            E Offline
            Eugen Podsypalnikov
            wrote on last edited by
            #8

            Very good :) And now, as Moak said, try :) :

            LPBYTE lpOut = *foo;
            cout << lpOut[0]; // is the garbage here ? :)

            virtual void BeHappy() = 0;

            1 Reply Last reply
            0
            • M Mike the Red

              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 use foo->operator LPBYTE() then Inside operator. appears in the output but not if I use an explicit cast (LPBYTE) foo. Any ideas on that one ? Thanks, MZR

              CPalliniC Offline
              CPalliniC Offline
              CPallini
              wrote on last edited by
              #9

              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]

              In testa che avete, signor di Ceprano?

              M 1 Reply Last reply
              0
              • C Cool_Dev

                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..

                M Offline
                M Offline
                Mike the Red
                wrote on last edited by
                #10

                I'm clear that m_buff is a pointer, and what I want is for (LPBYTE) foo to point to the same place m_buff points, not to point to m_buff itself. My class uses the buffer size to sometimes have m_buff point to a dynamically allocated BYTE 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 the testClass object, rather than the memory pointed to by m_buff. I think I said it in the original post, but I could accomplish this easily with a member function like

                LPBYTE getBuff() { return &this->m_buff[0]; };

                ..but I thought this was a good opportunity to learn about operator overloading. Thanks! MZR

                1 Reply Last reply
                0
                • CPalliniC CPallini

                  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]

                  M Offline
                  M Offline
                  Mike the Red
                  wrote on last edited by
                  #11

                  -nt-

                  CPalliniC 1 Reply Last reply
                  0
                  • M Moak

                    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)

                    M Offline
                    M Offline
                    Mike the Red
                    wrote on last edited by
                    #12

                    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 (true LPBYTE or LPBYTE 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 pointer m_buff.)

                    M 1 Reply Last reply
                    0
                    • M Mike the Red

                      -nt-

                      CPalliniC Offline
                      CPalliniC Offline
                      CPallini
                      wrote on last edited by
                      #13

                      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]

                      In testa che avete, signor di Ceprano?

                      1 Reply Last reply
                      0
                      • M Mike the Red

                        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 (true LPBYTE or LPBYTE 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 pointer m_buff.)

                        M Offline
                        M Offline
                        Moak
                        wrote on last edited by
                        #14

                        Good teamwork with Pallini :)

                        Webchat in Europe :java: (only 4K)

                        1 Reply Last reply
                        0
                        Reply
                        • Reply as topic
                        Log in to reply
                        • Oldest to Newest
                        • Newest to Oldest
                        • Most Votes


                        • Login

                        • Don't have an account? Register

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • World
                        • Users
                        • Groups