C++ Syntax Confusion

C

coder_lol

Given the template class below, please help me understand the
following code behavior?

Array<int32> ia(10); // Array that can contain 10 int32
ia[1] = 1; // Array element 1 set to 1

Here comes the confusion part.

Array<int32> *iarrayPtr = new Array<int32>(10);

1. Does the above mean a point to an array that can contain 10
int32 ?

(*iarrayPtr)[1] = 99;

2. Assign value 99 to array element 1.

iarrayPtr[2] = 100;

3. Stepping through with the debugger, I can see Array(int32 aSize)
called with aSize set to 100. What happened here? How should I read
the above code statement?

Thanks!!!

=== ===
template<class T>
class Array :{
public:
Array(int32 aSize){dataLen = aSize;data = new T[dataLen];}
virtual ~Array(){delete [] data;}

int32 length() const{return(dataLen);}

const T& operator[](int32 i) const {return(data);}

T& operator[](int32 i){return(data);}

T *getData() const {return(data);}

private:
Array();
private:
T *data;
int32 dataLen;
};
 
A

antonov84

Array<int32> *iarrayPtr = new Array<int32>(10);

1. Does the above mean a point to an array that can contain 10
int32 ?

Ya
2. Assign value 99 to array element 1.

iarrayPtr[2] = 100;

Here you're viewing your pointer as an array of Array<int32>
(pointers can be viewed as arrays, and an array can be viewed as r-
value pointer to its first element in C/C++). Thus you access its
third element (third Array<int32>, which you obviously didnt allocate
memory for). Now, when you toss 100 in there, an implicit convertion
takes place:

consturctor Array(int32 aSize) - gives compiler rights to implicitly
convert int32 to Array using this constructor. If you want to avoid
such errors, put explicit in front of constructor declaration:

explicit Array(int32 aSize);

Then you would need to type:

iarrayPtr[2] = Array<int32>(100);

for this to compile successfully.
 
D

dheeraj.khajuria

Given the template class below, please help me understand the
following code behavior?

Array<int32> ia(10); // Array that can contain 10 int32
ia[1] = 1; // Array element 1 set to 1

Here comes the confusion part.

Array<int32> *iarrayPtr = new Array<int32>(10);

1. Does the above mean a point to an array that can contain 10
int32 ?


hello,

according to my understanding ..In your first point..it means a
pointer of Array<int32> that points to Array<int32>(10). it's not
exactly pointing to array of 10 int32.
let take for exp..

int *ptr = new int(10); here it's pointing to integer that's
initialized to 10.
and
int *ptr = new int[10]; but here points to array of 10 integer;


although explicit conversion is there..in second case "iarrayPtr[2] =
100"..and one can avoid it using explicit keyword with the class
constructor..

but coming on to your third point..
3. Stepping through with the debugger, I can see Array(int32 aSize)
called with aSize set to 100. What happened here? How should I read
the above code statement?

How can Array(int32 aSize) constructor be called with 100 as
aSize??..when you are passing 10 as value.?

now see code below..made default constructor as public. Set the aSize
as "10";


Array<int32> *iarrayPtr = new Array<int32>[10];

now iarryPtr is pointer that points to Array of 10 Array<int32>(10).


typedef int int32;
using namespace std;

template<class T>
class Array {
public:
Array() {dataLen = 10;data = new T[dataLen];}
Array(int32 aSize){dataLen = aSize;data = new T[dataLen];}
virtual ~Array(){delete [] data;}

int32 length() const{return(dataLen);}

const T& operator[](int32 i) const {return(data);}

T& operator[](int32 i){return(data);}

T *getData() const {return(data);}

private:
// Array();
private:
T *data;
int32 dataLen;
};


int main()
{

Array<int32> ia(10); // Array that can contain 10 int32
ia[1] = 1; // Array element 1 set to 1


Array<int32> *iarrayPtr = new Array<int32>[10];


(*(iarrayPtr+9))[9] = 99;
cout <<(*(iarrayPtr+9))[9]<<endl;
iarrayPtr[9][9] = 100;
cout <<iarrayPtr[0].length()<<endl;
cout <<iarrayPtr[9][9]<<endl;

return 0;
}


pls let me know if i'm wrong somewhere..:).
 
B

BobR

Here comes the confusion part.

Array<int32> *iarrayPtr = new Array<int32>(10);

1. Does the above mean a point to an array that can contain 10
int32 ?

hello,
according to my understanding ..In your first point..it means a
pointer of Array<int32> that points to Array<int32>(10). it's not
exactly pointing to array of 10 int32.
let take for exp..

int *ptr = new int(10); here it's pointing to integer that's
initialized to 10.
and
int *ptr = new int[10]; but here points to array of 10 integer;


although explicit conversion is there..in second case "iarrayPtr[2] =
100"..and one can avoid it using explicit keyword with the class
constructor..

but coming on to your third point..
3. Stepping through with the debugger, I can see Array(int32 aSize)
called with aSize set to 100. What happened here? How should I read
the above code statement?

How can Array(int32 aSize) constructor be called with 100 as
aSize??..when you are passing 10 as value.?

now see code below..made default constructor as public. Set the aSize
as "10";


Array<int32> *iarrayPtr = new Array<int32>[10];

now iarryPtr is pointer that points to Array of 10 Array<int32>(10).

typedef int int32;
using namespace std;
template<class T> class Array { public:
Array() {dataLen = 10;data = new T[dataLen];}
Array(int32 aSize){dataLen = aSize;data = new T[dataLen];}
virtual ~Array(){delete [] data;}
int32 length() const{return(dataLen);}
const T& operator[](int32 i) const {return(data);}
T& operator[](int32 i){return(data);}
T *getData() const {return(data);}
private:
// Array();
private:
T *data;
int32 dataLen;
};


int main(){
Array<int32> ia(10); // Array that can contain 10 int32
ia[1] = 1; // Array element 1 set to 1
Array<int32> *iarrayPtr = new Array<int32>[10];
(*(iarrayPtr+9))[9] = 99;
cout <<(*(iarrayPtr+9))[9]<<endl;
iarrayPtr[9][9] = 100;
cout <<iarrayPtr[0].length()<<endl;
cout <<iarrayPtr[9][9]<<endl;
return 0;
}

pls let me know if i'm wrong somewhere..:).


Not wrong, but I'd use init lists:

template<class T> class Array{ public:
Array() : dataLen( 10 ), data( new T[dataLen] ){}
Array( int32 aSize )
: dataLen( aSize ), data( new T[dataLen] ){}
// alt: replace the 2 Ctors above with:
// Array( int32 aSize = 10 )
// : dataLen( aSize ), data( new T[dataLen] ){}

virtual ~Array(){ delete [] data;}
int32 length() const{return(dataLen);}
const T& operator[](int32 i) const {return(data);}
T& operator[](int32 i){return(data);}
T* getData() const {return(data);}
private: // note the order of the following.
int32 dataLen;
T *data;
};

And maybe use 'function-level try blocks':

template<class T> class Array{ public:
Array( int32 aSize = 10 )
try : dataLen( aSize ), data( new T[dataLen] ){}
catch( std::bad_alloc const &sba ){
// handle error and/or (re-)throw something.
}
// ......
};
 
J

James Kanze

Given the template class below, please help me understand the
following code behavior?
Array<int32> ia(10); // Array that can contain 10 int32
ia[1] = 1; // Array element 1 set to 1
Here comes the confusion part.
Array<int32> *iarrayPtr = new Array<int32>(10);
1. Does the above mean a point to an array that can contain 10
int32 ?

It's a pointer to a single array which can containt 10 elements,
yes.
(*iarrayPtr)[1] = 99;

Correct. Dereferencing the pointer results in the array itself.
2. Assign value 99 to array element 1.
iarrayPtr[2] = 100;

This is undefined behavior. For historical reasons, [] is
defined on pointers, and is the exactly equivalent (in this
case) of *(iarrayPtr + 2). In short, you are assigning 100 to
the third Array object allocated by new. Which is wrong for
several reasons: first, you didn't allocate three objects, only
one, so what you get it undefined behavior, and second, you
haven't defined an assignment operator for Array objects, so the
compiler generated one will be used, and I'm 100% certain it
doesn't do what you want (since it does a shallow copy).
Finally, of course, you're assigning an int, and not an Array
object, so in the absence of an explicit "operator=(int)" in
your Array class, the compiler will try to convert the int to an
Array object.
3. Stepping through with the debugger, I can see Array(int32 aSize)
called with aSize set to 100. What happened here?

The compiler is doing what you told it to do, not what you
actually want:). See my answer to 2. Also, you "told" the
compiler that it could implicitly convert an int to an Array
object.
=== ===
template<class T>
class Array :{
public:
Array(int32 aSize){dataLen = aSize;data = new T[dataLen];}
virtual ~Array(){delete [] data;}

int32 length() const{return(dataLen);}

const T& operator[](int32 i) const {return(data);}

T& operator[](int32 i){return(data);}

T *getData() const {return(data);}

private:
Array();
private:
T *data;
int32 dataLen;
};


Given this:
-- you definitly want to declare the constructor explicit, and
-- you either want to define a copy constructor and assignment
operator with the semantics you want, or declare them
private, so that the compiler can't use them just anywhere.
Neither of these corrections, however, will allow you to refer
the the third Array object when you've only allocated one.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,175
Latest member
Vinay Kumar_ Nevatia
Top