default assignment operator

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • stmfc
    New Member
    • May 2007
    • 65

    default assignment operator

    while assigning on object to another,
    default assignment operator written by compiler
    makes memberwise copying that why there isn't any problem with
    types like (int ,double etc) but it cannot copy strings, these are ok.
    what i dont understand is how it can manage assigning arrays.
    let me explain with an example:

    Code:
    class myClass {
      int val1;
      char *str;
      int array[5];
    };
    
    myClass B;   // create object B
    myClass A=B;   // initialize object A with object B
    val1 --> A.val1= B.val1 this is valid and ok for me
    str ---> A.str=B.str this is invalid and ok for me
    array--> A.array=B.array this is valid but how? and why?
    Last edited by AdrianH; May 4 '07, 03:02 PM. Reason: Please use [code][/code] tags
  • Ganon11
    Recognized Expert Specialist
    • Oct 2006
    • 3651

    #2
    This works because the arrays in each class are just variables. In this case, though, it's not a good idea to copy them like this. The value actually being stored in A.array and B.array are pointers - addresses in memory where the 5 integers will actually be stored. When you type A.array = B.array, you are giving A.array the same memory address that B.array was holding. Now A.array and B.array are pointing to the same memory.

    But what happens when, say, B goes out of scope? It is de-allocated, and the memory pointed to by B.array is erased. But A.array is still pointing to that same place, and is now useless!

    I can't seem to successfully post how you should go about this; stupid school computer. Perhaps one of my colleagues can finish my explanation.

    Comment

    • AdrianH
      Recognized Expert Top Contributor
      • Feb 2007
      • 1251

      #3
      Originally posted by Ganon11
      This works because the arrays in each class are just variables. In this case, though, it's not a good idea to copy them like this. The value actually being stored in A.array and B.array are pointers - addresses in memory where the 5 integers will actually be stored. When you type A.array = B.array, you are giving A.array the same memory address that B.array was holding. Now A.array and B.array are pointing to the same memory.

      But what happens when, say, B goes out of scope? It is de-allocated, and the memory pointed to by B.array is erased. But A.array is still pointing to that same place, and is now useless!

      I can't seem to successfully post how you should go about this; stupid school computer. Perhaps one of my colleagues can finish my explanation.
      Sorry Ganon, not quite right. The array is not stored on the seperatly, but is an aggregate item (C/C++ term, UML states this as a composite item. Grrr, just found out that UML uses different terms from C/C++ :(), so the entire array is copied.

      If it were a pointer to an array (UML may state this as a aggregate association, though you can have something that is physicly seperated from the main object and still have a composition association) you would be correct in that only the pointer would be coped, just like the c-string that OP stated in his/her example. In which case, it would cause a problem when doing memory cleanup. If not done properly, you could have an object pointing at another that is not there (has been deleted by the other owning object).


      Adrian

      Comment

      • Ganon11
        Recognized Expert Specialist
        • Oct 2006
        • 3651

        #4
        So because the array was declared with the braces [], it will be copied correctly? But if the array had been declared as a pointer, then what I said would hold true, right?

        Comment

        • AdrianH
          Recognized Expert Top Contributor
          • Feb 2007
          • 1251

          #5
          Originally posted by Ganon11
          So because the array was declared with the braces [], it will be copied correctly? But if the array had been declared as a pointer, then what I said would hold true, right?
          Except for the fact that [] are called brackets (I know its a detail, but I didn’t make the terminology ;). Further, {} are braces and () are parentheses.) yes.


          Adrian

          Comment

          • Ganon11
            Recognized Expert Specialist
            • Oct 2006
            • 3651

            #6
            Hey, I'm a programmer, and I can typedef brackets into braces and vice versa! :P

            Comment

            • stmfc
              New Member
              • May 2007
              • 65

              #7
              thnaks a lot, but i am still confused.
              we cannot directly assign an array to another array,
              but if we put the array in a class we can assign the class directly to another class (so the array is directly assigned too).
              is not it bit strange?

              Comment

              • AdrianH
                Recognized Expert Top Contributor
                • Feb 2007
                • 1251

                #8
                Originally posted by stmfc
                thnaks a lot, but i am still confused.
                we cannot directly assign an array to another array,
                but if we put the array in a class we can assign the class directly to another class (so the array is directly assigned too).
                is not it bit strange?
                Strange? I guess, but in a nice way. ;)

                You are right an array cannot be assigned to another array. But when it is wrapped up in a class/struct, it becomes just a bunch of individual objects that are member-wise copied. I cannot quote the reason from the C spec as to why this occurs, it just the way it is.


                Adrian

                Comment

                • weaknessforcats
                  Recognized Expert Expert
                  • Mar 2007
                  • 9214

                  #9
                  First of all this code crashes:
                  Originally posted by stmfc
                  class myClass {
                  int val1;
                  char *str;
                  int array[5];
                  };

                  myClass B; // create object B
                  myClass A=B; // initialize object A with object B
                  The default assignment operator the compuiler uses is for the built-in types only.

                  In the case of the array member, this is a STACK variable. The name "array" is the address of element 0. So, the name "array" is a char*. The default assignment for a char* is to just copy the pointer. All that happens is:
                  Code:
                  A.array = B.array;
                  meanng the only the ADDRESS of the array in B is copied.

                  BUT, the target array in A is also a STACK variable. You cannot change the address of a stack variable. You crash at this point.

                  You must copy the array element by element:

                  Code:
                  A::A(const B& rhs)
                  {
                      for (int ctr=0; ctr< 5; ++ctr)
                      {
                           this->array[ctr] = rhs.array[ctr];
                      }
                  }
                  It makes no difference whatsoever whether [] were used or not. In C++ you can never copy arrays using an assignment operator. Things like this is precisely why the vector template was created.

                  The class member should be:
                  Code:
                  class myClass {
                    int val1;
                    char *str;
                    vector<int> array;
                  };
                  If you use a vector<int>, the orignal code works as written because the assignment operator for vector will do the copy.

                  Comment

                  • AdrianH
                    Recognized Expert Top Contributor
                    • Feb 2007
                    • 1251

                    #10
                    Originally posted by weaknessforcats
                    First of all this code crashes:

                    The default assignment operator the compuiler uses is for the built-in types only.

                    In the case of the array member, this is a STACK variable. The name "array" is the address of element 0. So, the name "array" is a char*. The default assignment for a char* is to just copy the pointer. All that happens is:
                    Code:
                    A.array = B.array;
                    meanng the only the ADDRESS of the array in B is copied.
                    Sorry but this is wrong. See up thread for an explanation.

                    For a simple example of this working try the following code:
                    Code:
                    #include <iostream>
                    using namespace std;
                    
                    struct A
                    {
                      int array[3];
                    };
                    
                    int main() {
                      A a = {{1,2,3}};
                      A b = a;
                      for (int i = 0; i < 3; ++i) {
                        cout << "a.array[" << i << "] = " << a.array[i] << endl;
                        cout << "b.array[" << i << "] = " << b.array[i] << endl;
                      }
                      return 0;
                    }
                    As you will see, the assignment works.


                    Adrian

                    Comment

                    • weaknessforcats
                      Recognized Expert Expert
                      • Mar 2007
                      • 9214

                      #11
                      Originally posted by AdrianH
                      As you will see, the assignment works.
                      Yes, I do. I got sidetracked by Visual Studio.NET which crashes because the A array is not initialized in the original code. You initialized it to 1,2,3. Visual Studio.NET crashes if you use uninitialized variables.

                      Comment

                      • AdrianH
                        Recognized Expert Top Contributor
                        • Feb 2007
                        • 1251

                        #12
                        Originally posted by weaknessforcats
                        Yes, I do. I got sidetracked by Visual Studio.NET which crashes because the A array is not initialized in the original code. You initialized it to 1,2,3. Visual Studio.NET crashes if you use uninitialized variables.
                        I wouldn't be surprised if Visual Studio crashes if you sneeze in a certain way. ;)

                        Actually, if you start doing things with undefined variables, the result is undefined so it is possible that it got overlooked.


                        Adrian

                        Comment

                        Working...