I’m trying to self-teach myself C++, and once again I got stuck on something and can’t seem to fix it.
Please excuse the horrible mess of a code that you’re about to see. This is also my first post on this site, so the post’s format will probably be off too, sorry.
There are two files: main.cpp and vect1.h
(no vect1.cpp because it seems templates like to only hang out in header files)
main.cpp:
#include <iostream>
#include "vect1.H"
using namespace std;
int main(){
vect1<int> inst1(10);
inst1[9]=4;
cout<<inst1[9]<<endl;
//-----
vect1<double> inst2(10);
inst2[5]=5.112;
cout<<inst2[5]<<endl;
//-----
//====PART 2=====//
cout<<"--------"<<endl;
inst2[9]=999;
cout<<inst2[9]<<endl;
//inst2.pop();
inst2.push(2);
cout<<inst2[9]<<endl;
cout<<inst2[10]<<endl;//New block
system("PAUSE");
return 0;}
vect1.h:
#ifndef VECT1_H
#define VECT1_H
#include <iostream> //DEBUG
template <class T>
class vect1{
private:
T *ptr;
T total; //work on this
int units;
int counter;
public:
//vect1();
vect1(T);
vect1();
T &operator[](const int &);
void pop();
void push(T);
};
//---------------------
/*
template <class T>
vect1<T>::vect1(){
ptr = new int [0];
}
*/
template <class T>
vect1<T>::vect1(T number){
ptr = new T [number];
total=0;
units=(int)number;
for(counter=0;counter<number;counter++){
ptr[counter]=0;
}
}
/* now the destruct is giving me errors...
template <class T>
vect1<T>::~vect1(){
total=0;
delete[] ptr;
}*/ //<<this line tosses a C2039 error
template <class T>
T &vect1<T>::operator[](const int & ref){
if(ref>0 && ref<(units)){
return ptr[ref];
}else{
throw "Error! Out of range!"; //<<make catch
}
}
//--------
template <class T>
void vect1<T>::pop(){
units = (units-1);
T *tempPtr;
tempPtr = new T[units];
for(counter=0;counter<units;counter++){
tempPtr[counter]=ptr[counter];
}
delete[] ptr;
ptr = new T[units];
for(counter=0;counter<units;counter++){
ptr[counter]=tempPtr[counter];
}
delete[] tempPtr;
}
//--
template <class T>
void vect1<T>::push(T pushnum){
units++;
const int newsize=(int)units; //<<<<<
T *tempPtr;
tempPtr = new T[units];
for(counter=0;counter<(units-1);counter++){
tempPtr[counter]=ptr[counter];
}
//tempPtr[(int)units]=pushnum;
delete[] ptr;
std::cout<<units<<std::endl;//<<DEBUG
ptr = new T[units];
for(counter=0;counter<(units-1);counter++){
ptr[counter]=tempPtr[counter];
//ptr[9]=101;
}
ptr[newsize]=pushnum; /* <<bleh */
//ptr[newsize]=12321; //DEBUG //<<Even this isn't working...
delete[] tempPtr;
}
//---------------------
#endif
output(in the console):
4
5.112
--------
999
11
999
-6.27744e+066
Press any key to continue . . .
The plan is to make it so when you pop() it will create a new temp array of T and copy everything but the last block from the original to the temp array, delete the original array, and then create a new array one size smaller than before and send everything back, deleting the temp array. Same idea for the push(number), only the opposite. Push would copy itself to temp, push would delete itself and then re-create itself as 1 size bigger, then send everything from temp to push and delete temp. Then send the number sent with push into the new block. So this program should print out ‘2’ after the second “999” line. But instead I get “-6.27744e+066”.
Pop() seems to work. Sorta. Having real issues with push(num) though. I also seem to suddenly get a C2039 error from my destructor. It wasn’t doing that before, and I’ve yet to change anything in it.
I would really appreciate it if someone could look over this mess and give me some tips on what to fix. Thanks!
I use Visual Studio 2010 as my compiler.
This is my build log(with some nice errors/warnings to go with it!):
1>------ Rebuild All started: Project: chapter 16-5, Configuration: Debug Win32 ------
1>Build started 2/9/2012 5:34:01 PM.
1>_PrepareForClean:
1> Deleting file "Debug\chapter 16-5.lastbuildstate".
1>InitializeBuildStatus:
1> Creating "Debug\chapter 16-5.unsuccessfulbuild" because "AlwaysCreate" was specified.
1>ClCompile:
1> main.cpp
1>e:\programming(cpp)\chapter 16-5\chapter 16-5\vect1.h(31): warning C4244: 'initializing' : conversion from 'double' to 'unsigned int', possible loss of data
1> e:\programming(cpp)\chapter 16-5\chapter 16-5\vect1.h(30) : while compiling class template member function 'vect1<T>::vect1(T)'
1> with
1> [
1> T=double
1> ]
1> e:\programming(cpp)\chapter 16-5\chapter 16-5\main.cpp(11) : see reference to class template instantiation 'vect1<T>' being compiled
1> with
1> [
1> T=double
1> ]
1>Manifest:
1> Deleting file "Debug\chapter 16-5.exe.embed.manifest".
1>LinkEmbedManifest:
1> chapter 16-5.vcxproj -> E:\Programming(CPP)\chapter 16-5\Debug\chapter 16-5.exe
1>FinalizeBuildStatus:
1> Deleting file "Debug\chapter 16-5.unsuccessfulbuild".
1> Touching "Debug\chapter 16-5.lastbuildstate".
1>
1>Build succeeded.
1>
1>Time Elapsed 00:00:10.62
========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========
This constructor allocates space for
numberobjects, butnumberhas general typeTand you cast it toint. If you want to have a vector of strings or objects, conversion to int fails.numbershould have type int. Casting is generally not needed and it could be a symptom of bad design (except inheritance – dynamic_cast).Because
Tcould be anything you can’t initialize it in constructor and you must leave it to the user of your vector.You use const reference because you were probably told that it is faster than passing by value. Well this is true for larger objects, not for int. Reference is basically just another pointer (with different syntax). The function is passed an address to the target variable. Pointer and int are usually equally large so there is no improvement here and accessing through pointer is definitely slower than directly accessing the value.
There is no need to copy data back to
ptrit is enough to copy the pointer.And add the destructor releasing allocated memory.
I hope this helped and I am sorry for my bad English.