Assigning data member while object initialization

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • iammilind
    New Member
    • Sep 2006
    • 14

    Assigning data member while object initialization

    (1) Is following code at Line-1 an undefined behavior for different compilers ? (it works fine with linux g++ compiler)
    (2) If you comment the operator = (), and try to assign the object with a pointer (Line-3), still the code gets compiled, Why ? (actually it's instantiates the constructor !)
    (3) In continuation, Why does the pn.size get garbaged when assigned with a pointer ?

    Code:
    template<class TYPE>
    struct Arr{
    TYPE *ptr;
    int size;
    Arr(TYPE *p=0) : ptr(p) { }
    // Arr& operator = (TYPE *p) { delete[] ptr; ptr = p; return *this;}
    void print () { cout<<"ptr = "<<ptr<<" and size = "<<size<<endl; }
    ~Arr() { delete[] ptr; }
    };
    
    int main()
    {
    Arr<int> pn = new int[pn.size = 10]; // Line-1
    pn.print(); // Line-2
    pn = new int[pn.size = 5]; // Line-3
    pn.print(); // Line-4
    }
  • rstiltskin
    New Member
    • Feb 2010
    • 14

    #2
    1. It's normal behavior. To a C++ compiler
    Arr<int> pn = new int[pn.size = 10];
    is equivalent to
    Arr<int> pn(new int[pn.size = 10]);
    In fact, you can even define an int variable with the value 5 this way
    int i(5);
    in C++ (but not in C).

    2. Since you are using an int* to assign to a Arr object, the compiler is using the constructor as an implicit conversion operator, so yes, it's calling the constructor. If, on the other hand, you declared the constructor explicit, like so:
    explicit Arr(TYPE *p=0) : ptr(p) {}
    you would generate a compiler error unless you provide an assignment operator.

    3. As you said, it's calling the constructor, but think about the sequence of events. It creates a new (unnamed) Arr object, then evaluates the expression inside the brackets [pn.size = 5], but at this time pn is the original Arr object, not the new one, so it changes the size variable of the old pn to 5. Then it allocates an array of 5 ints and assigns that to the new Arr's ptr but doesn't assign any value to its size variable. Finally it assigns that new object to pn, so when you print this pn the size value is still garbage.

    The way you wrote your constructor and assignment operator, your calling function is doing things (allocating the arrays) that should be done in the class. If you're doing that so that you can resize the arrays, why not write them this way and add a resize() function to the class:
    Code:
    template<class TYPE>
    struct Arr{
      TYPE *ptr;
      int size;
      Arr(int s=0) : size(s) {
        ptr = new TYPE[s];
      }
      Arr& operator = (const Arr &rhs) {
         delete[] ptr;
         ptr = new TYPE[size = rhs.size];
         return *this;
      }
      void print () { cout<<"ptr = "<<ptr<<" and size = "<<size<<endl; }
    
      ~Arr() { delete[] ptr; }
    
    };
     
    int main()
    {
      Arr<int> arr;
      arr.print();
      Arr<int> arr2(5);
      arr2.print();
      arr = arr2;
      arr.print();
    }

    Comment

    Working...