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 Offline
    M Offline
    Mike the Red
    wrote on last edited by
    #1

    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.

    M C C E 4 Replies 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.

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

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

        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
            • C 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

              C 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

                    C Offline
                    C 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]

                    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
                      • C 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-

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

                            C Offline
                            C 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]

                            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