473,387 Members | 1,517 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

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 ?

Expand|Select|Wrap|Line Numbers
  1. template<class TYPE>
  2. struct Arr{
  3. TYPE *ptr;
  4. int size;
  5. Arr(TYPE *p=0) : ptr(p) { }
  6. // Arr& operator = (TYPE *p) { delete[] ptr; ptr = p; return *this;}
  7. void print () { cout<<"ptr = "<<ptr<<" and size = "<<size<<endl; }
  8. ~Arr() { delete[] ptr; }
  9. };
  10.  
  11. int main()
  12. {
  13. Arr<int> pn = new int[pn.size = 10]; // Line-1
  14. pn.print(); // Line-2
  15. pn = new int[pn.size = 5]; // Line-3
  16. pn.print(); // Line-4
  17. }
Feb 4 '10 #1

✓ answered by rstiltskin

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:
Expand|Select|Wrap|Line Numbers
  1. template<class TYPE>
  2. struct Arr{
  3.   TYPE *ptr;
  4.   int size;
  5.   Arr(int s=0) : size(s) {
  6.     ptr = new TYPE[s];
  7.   }
  8.   Arr& operator = (const Arr &rhs) {
  9.      delete[] ptr;
  10.      ptr = new TYPE[size = rhs.size];
  11.      return *this;
  12.   }
  13.   void print () { cout<<"ptr = "<<ptr<<" and size = "<<size<<endl; }
  14.  
  15.   ~Arr() { delete[] ptr; }
  16.  
  17. };
  18.  
  19. int main()
  20. {
  21.   Arr<int> arr;
  22.   arr.print();
  23.   Arr<int> arr2(5);
  24.   arr2.print();
  25.   arr = arr2;
  26.   arr.print();
  27. }
  28.  

1 1464
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:
Expand|Select|Wrap|Line Numbers
  1. template<class TYPE>
  2. struct Arr{
  3.   TYPE *ptr;
  4.   int size;
  5.   Arr(int s=0) : size(s) {
  6.     ptr = new TYPE[s];
  7.   }
  8.   Arr& operator = (const Arr &rhs) {
  9.      delete[] ptr;
  10.      ptr = new TYPE[size = rhs.size];
  11.      return *this;
  12.   }
  13.   void print () { cout<<"ptr = "<<ptr<<" and size = "<<size<<endl; }
  14.  
  15.   ~Arr() { delete[] ptr; }
  16.  
  17. };
  18.  
  19. int main()
  20. {
  21.   Arr<int> arr;
  22.   arr.print();
  23.   Arr<int> arr2(5);
  24.   arr2.print();
  25.   arr = arr2;
  26.   arr.print();
  27. }
  28.  
Feb 6 '10 #2

Sign in to post your reply or Sign up for a free account.

Similar topics

14
by: David Gausebeck | last post by:
The inability to denote data members as read-only in C++ is something which has annoyed me (slightly) for a while now. You can always get around it with accessor methods that return const...
5
by: Dave | last post by:
Hello all, Please consider the code below. It is representative of a problem I am having. foo_t needs to contain a bar_t which is a class without a copy constructor or operator=. It is not...
37
by: Dave | last post by:
Hello all, Please consider the code below. It is representative of a problem I am having. foo_t needs to contain a bar_t which is a class without a copy constructor or operator=. It is not...
11
by: Bob Hairgrove | last post by:
The following class contains start and end points of a range of values. The range can have a direction which is implied from the relative order of start and end, or it can be without direction. IOW...
3
by: Tran Tuan Anh | last post by:
Dear all, I am new with C++ and very confused with some features. Really appreciate if you can explain to me some of stuffs below. I define a class: class A { static A* instance = 0; };
3
by: Mike - EMAIL IGNORED | last post by:
MyClass { //I have a static member method: void static myMethod(); //and a static data member: static MyType myData; }; //In the .cpp file: void MyClass::myMethod()
7
by: The|Godfather | last post by:
Hi everybody, I read Scotte Meyer's "Effective C++" book twice and I know that he mentioned something specific about constructors and destructors that was related to the following...
6
by: gs | last post by:
Hi, I want to know that when memory get allocated to static data member of a class. class A { static int i; }
15
by: akomiakov | last post by:
Is there a technical reason why one can't initialize a cost static non- integral data member in a class?
7
by: krishna | last post by:
What is the need of this syntax for initializing values, isn't this ambiguous to function call? e.g., int func_name(20); this looks like function call (of course not totally as there is no...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.