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.

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

    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]

    In testa che avete, signor di Ceprano?

    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.

      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