Class Templates, Pointers, and transferring data between class objects

M

Malciah

I posted this on another site, but so far I've had no answers.
So, I decided to try it here.
--------------------------------------------------------
I've been learning C++ for about 6 weeks now, and I've been able to
figure out the cause
of pretty much every problem I've run into.

This time, I'm at a loss. The book I'm learning from isn't the
greatest in the world, and it hasn't
given me a good explanation since chapter 6. (I'm in chapter 11
now)

I am learning about template classes, and how to transfer data between
two objects of the same class with pointers involved.

I was shown how to make the code "safe" by adding a copy constructor,
an overloaded assignment operator, and a destructor.

The code only had one object, and I tried to add another object so I
could see if the code worked,
and boom. Problem.

The code compiles with no errors, however when you run it, it gets to
the last 'for' loop and crashes.

Actually, it only crashes if you try to display the values inside the
'newScores' array.
If you remove the last 'cout', it runs with no problem.

Here's the code:

--------------------------------------------------------
#include <iostream>
using namespace std;

template <class T>
class Array
{
T *ptr_to_array;
int number;
public:
Array( int number_of_elements ); // constructor
declaration.
Array( const Array &a ); // copy
constructor declaration.
~Array();
T& operator=( const Array
&a ); // overload the equal
operator.
T& operator[]( int index ){ return ptr_to_array[index]; } //
overload the array index.
};

template <class T>
Array<T>::Array( int number_of_elements ) // constructor
definition.
{
number = number_of_elements;
ptr_to_array = new T[number];
}

template <class T>
Array<T>::Array( const Array &a )
{
number = a.number; // copy
constructor definition.
T *ptr_to_array = new T[number];

for( int index = 0; index < number; index++ )
{
ptr_to_array[index] = a.ptr_to_array[index];
}
}

template <class T>
T& Array<T>::eek:perator=( const Array &a )
{
if ( this == &a ) return *this;
delete[] ptr_to_array;

number = a.number; // overloaded
assignment operator.
T *ptr_to_array = new T[number];

for( int loop = 0; loop < number; loop++ )
{
ptr_to_array[loop] = a.ptr_to_array[loop];
}

return *this;
}

template <class T>
Array<T>::~Array() // Destructor.
{
delete[] ptr_to_array;
}



int main()
{

const int nmbr_kids[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; // Used
to initialize the first object.
Array<float> scores( 10 );

for( int loop = 0; loop < 10; loop++ )
{
scores[loop] = nmbr_kids[loop]; // Initializing first object
array.
}

for( int loop = 0; loop < 10; loop++ )
{ //
Displaying first array.
cout << "This is the value in scores element" << loop << ": " <<
scores[loop] << endl;
}
cout << "\n\n";


// Problem starts below...

Array<float> newScores( scores ); // New object.

// newScores = scores; /* *** See Below *** */


for( int loop = 0; loop < 10; loop++ ) // Display second
array.
{
cout << "This is the value in newScores element" << loop << ": " <<
newScores[loop] << endl;
}

return 0;
}


--------------------------------------------------------

/* *** I ran out of ideas, so I tried adding this line as you see. I
also tried it like this: *
* newScores[10] = scores[10]; & newScores[] = scores[];
They didn't work either *** */

I added the array to the constant integer (originally, it initialized
to 5), and the 'for' loops
in main. (the ones in the method definitions are from the book)

Sorry it's so long...

I'm starting to understand why there's a book dedicated to C++
templates.

If it's not too much to ask, could you also explain why this code
needs the overloaded
assignment operator?
I understand the copy constructor... But the overloaded assignment is
a mystery.

I appreciate any help that anyone can give me on this. It's been
driving me crazy for 4 days
Thank you in advance,

-Malciah
 
O

Obnoxious User

Malciah skrev:
I posted this on another site, but so far I've had no answers.
So, I decided to try it here.
--------------------------------------------------------
I've been learning C++ for about 6 weeks now, and I've been able to
figure out the cause
of pretty much every problem I've run into.
[snip]

Here's the code:

--------------------------------------------------------
#include <iostream>
using namespace std;

template <class T>
class Array
{
T *ptr_to_array;
int number;
public:
Array( int number_of_elements );
Array( const Array &a );
~Array();
T& operator=( const Array
&a ); // overload the equal
operator.
T& operator[]( int index ){ return ptr_to_array[index]; }
};

template <class T>
Array<T>::Array( int number_of_elements )
{
number = number_of_elements;
ptr_to_array = new T[number];
}

template <class T>
Array<T>::Array( const Array &a )
{
number = a.number;
T *ptr_to_array = new T[number];

ptr_to_array = new T[number];
 
P

p.lepin

I posted this on another site, but so far I've had no
answers.
So, I decided to try it here.

There are reasons not to use tabs for indentation and wrap
lines to some sensible right margin. My $J fingers are
aching from making your code compilable.
#include <iostream>
using namespace std;

Boo! Don't do that.
Array( const Array &a );

Shouldn't that be?

Array ( const Array said:
T& operator=( const Array &a );

Array said:
template <class T>
Array<T>::Array( const Array &a )

Array said:
T *ptr_to_array = new T[number];

ptr_to_array = new T [ number ] ;
template <class T>
T& Array<T>::eek:perator=( const Array &a )

Array < T > & Array < T > :: operator =
( const Array said:
T *ptr_to_array = new T[number];

ptr_to_array = new T [ number ] ;
 
M

Malciah

Thank you both so much!

I tried it your way first Pavel, and it worked wonderfully!

Then I tried just removing the T and dereference operator
(indirection) from the copy constructor, and the assignment overload
method, and that also worked.

I can't imagine why the author had me trying to create a new pointer.
I thought that was odd... I should have caught it.

Anyway, let me apologize...

First, I can only imagine you are booing my "using namespace std;"
Sorry, I know I shouldn't use it a lot (if at all), but I'm only
using it while I learn.
I move into namespaces in the next chapter, so I'll learn better
practices soon.

Second, the indentation.
This too, I am only doing while I learn. I plan on working on my
style once I have a firm grasp of the language.

Hitting the tab key is an old habit that followed me into this. Sorry
again.


Thanks again! I feel so much better now.

-Malciah
 
J

James Kanze

There are reasons not to use tabs for indentation and wrap
lines to some sensible right margin. My $J fingers are
aching from making your code compilable.

J will work no matter where you are in the line, so you don't
need $J. (But at least you're using the one true editor:).)

Seriously, of course, anyone posting to a news group should
check line length before hand (and avoid tab's). It's not that
difficult.
Boo! Don't do that.
Shouldn't that be?
Array ( const Array < T > & a ) ;

Same thing. Within a class template, any reference to the name
of the template which is not followed by a < is automatically
assumed to be the current instantiation.

For beginners, too, I'd recommend post-fixing the const, e.g.:

Array( Array const& other ) ;
Array < T > & operator = ( const Array < T > & a ) ;

The T& as a return value (instead of Array&) is a bit
surprising. (For the rest, the above comments hold.)

--
 
J

James Kanze

Second, the indentation.
This too, I am only doing while I learn. I plan on working on my
style once I have a firm grasp of the language.
Hitting the tab key is an old habit that followed me into this. Sorry
again.

You should get a decent editor. Which auto-indents, so you
generally don't have to indent manually. And which will convert
any tab you do insert into the correct number of spaces. (If I
turn off auto-indent, I use the tab key for indentation as well.
But no tab characters make it into the source file... except
when I'm writing makefiles:).)
 
P

p.lepin

J will work no matter where you are in the line, so you
don't need $J. (But at least you're using the one true
editor:).)

vim: learn something new every day. On the other hand,
that's quite logical now that I think about it.
Same thing. Within a class template, any reference to
the name of the template which is not followed by a < is
automatically assumed to be the current instantiation.

I should've mentioned that my C++ is awfully rusty.
However, being somewhat verbose for clarity's sake still
sounds like a good practice to me.
 
M

Marcus Kwok

James Kanze said:
J will work no matter where you are in the line, so you don't
need $J. (But at least you're using the one true editor:).)

Seriously, of course, anyone posting to a news group should
check line length before hand (and avoid tab's). It's not that
difficult.

Before posting code to the newsgroup, I do "s/\t/ /g" to convert tabs
to 4 spaces (8 spaces is a bit too much for my taste).
 
J

James Kanze

Before posting code to the newsgroup, I do "s/\t/ /g" to convert tabs
to 4 spaces (8 spaces is a bit too much for my taste).

How did the tabs get into the text to begin with? My editor
won't put a tab into what it writes to disk. (For various
reasons, I read news via Google; Firefox + "It's all text!"
means that I edit my postings with the same editor I use for
everything else.)
 

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

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top