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.

    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.

      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