Try to put own Class to creating by me <Template> like vector. unknow compile error
This is study project because of this I don't use code from STL vector. I want to create some program that will be do next:
1. Create object of class for example Point (class that has x,y coordinate)
2. Create object of name "Array" with fix amount of elements.
3. Put object of class Point to Array on needed me place that represent index of Array. Using fucntion SetElement
4. Using function GetElement I want to this this "Point" object on screen. Very simple, please help !!! What I did wrong ???
5. I create object of "Point " dynamically because of condition of study project.
My compiler error: compiler show my like windows message that name "MS Visual C++ Debag Library " and tell "Debag Error! Probram: c: \ bla lba \ debag \ 42a.exe Invalid allocation size 4229837429587 bytes... "
Please I really just want to see correction of code even without comments... Thanks in advance
Code:
// Array.h
// Templated Array class containging Ts
#include <sstream>
#include <iostream>
#ifndef Array_H
#define Array_H
template <class Type> class Array
{
private:
Type* m_data;
int m_size;
public:
Array<Type>();
Array<Type>(int new_size);
void SetElement(Type& type_object, int index);
const Type& GetElement(int index) const;
~Array();
};
#ifndef Array_cpp
#include "array.cpp"
#endif
#endif
//point1.h
#include "array.h"
#include <sstream>
#include <iostream>
using namespace std;
class Point
{
private:
double m_x;
double m_y;
public:
// Constructors
Point(): m_x(0), m_y(0) {};
Point(double new_x, double new_y) : m_x(new_x), m_y(new_y) {};
friend ostream& operator << (ostream& os, const Point& point)
{
return os << point.ToString();
}
std::string Point::ToString(void) const // create a string representation of a point
{
// create a string like: “Point(1.5, 3.9)”
std::ostringstream os;
os << m_x << " , " << m_y;
std::string double_string = os.str();
return "Point(" + double_string + ")";
}
};
//array.cpp
#include "array.h"
#include <sstream>
#include <iostream>
using namespace std;
#ifndef Array_CPP
#define Array_CPP
template <class Type>
Array<Type>::Array()
{
m_size = 10;
m_data = new Type[m_size];
}
template <class Type>
Array<Type>::~Array()
{
//delete* m_data;
}
template <class Type>
Array<Type>::Array(int new_size)
{
new_size = m_size;
m_data = new Type[m_size];
}
template <class Type>
void Array<Type>::SetElement(Type& type_object, int index)
{
try
{
if (index >= m_size){throw 11;}
m_data[index] = type_object;
cout << "Set Element " << type_object << endl;
}
catch (int x )
{
cout << "ERROR" << x << " ignore the set, because index of element bigger then massive size"<< endl;
}
}
template <class Type>
const Type& Array<Type>::GetElement(int index) const
{
try
{
if (index > m_size || index < 0){ throw 1;}
}
catch (double x)
{
cout << "index incorrect, index too big or too small " << x << endl;
}
return m_data[index];
}
#endif //Array_CPP
//main.cpp
#include "point1.h"
#include <iostream>
#include <sstream>
#include "array.cpp"
using namespace std;
int main()
{
Point *p1 = new Point (1,12);
cout << endl;
Array<Point> arr1(2);
arr1.SetElement(*p1,0);
cout << endl;
arr1.GetElement(0) ;
delete p1;
return 0;
}
Why is the destructor commented out? By commenting this out, your code is automatically buggy to begin with. You allocate in the constructor and fail to delete the memory in the destructor.
We can keep going around and around with this -- you've started at least 3 threads concerning this same class, and instead of taking what was stated in the last thread (by I believe monarch_dodra), you go ahead and do the wrong things over and over again.
Start off with a properly working Array class that knows how to copy and destroy itself safely and without bugs. That was given to you in the other thread. Don't go and start doing your own thing, because evidently you are not proficient in pointers and dynamically allocated memory.
#include "array.h"
class Point
{
private:
double m_x;
double m_y;
public:
Point(double new_x = 0, double new_y = 0) : m_x(new_x), m_y(new_y) {}
};
int main()
{
Point p1(1,12);
Array<Point> arr1(2);
arr1.SetElement(p1,0);
arr1.GetElement(0);
}
That is a complete program that compiles successfully and uses exactly what was given to you in the other thread. Added are those GetElement and SetElement functions.
Note there is no try/catch in those functions. It makes no sense whatsoever to put try/catch there -- let the code that uses the Array class do the try/catch. The only thing that makes some sense is the throw.
Second, note that all of that fluff with cout is removed. Also main() does not make unnecessary calls to "new" (I told you this already in the other thread, but again, you didn't change your code and/or ignored the advice).
Now, take the code above, compile it and run it. Are there any runtime errors? If there are no runtime errors and things work, then use what was given to you to go further. It isn't helpful that you're given advice, and instead of using that advice, you create another discussion thread using the same buggy Array class.
Regards,
Paul McKenzie
Last edited by Paul McKenzie; June 18th, 2012 at 03:34 AM.
Re: Try to put own Class to creating by me <Template> like vector. unknow compile err
Code:
Please I really just want to see correction of code even without comments... Thanks in advance
Unfortunately, you should consider that what you'll find here is exactly the opposite. Nobody will straight up correct your code. On the contrary, we'll take the time to try to teach you, and hope you'll find the problem yourself. We're not here to do/correct your homework, but we can still help.
----
First: Set:
Code:
template <class Type>
void Array<Type>::SetElement(Type& type_object, int index)
{
try
{
if (index >= m_size){throw 11;}
m_data[index] = type_object;
cout << "Set Element " << type_object << endl;
}
catch (int x )
{
cout << "ERROR" << x << " ignore the set, because index of element bigger then massive size"<< endl;
}
}
What the **** is this ****? You are throwing around ints, catching them in the same method, and then squelching the error.
If the caller made a mistake, there is nothing wrong with throwing an exception. That's the callers problem, and your responsibility is to throw an something at him:
BTW: const correctness when passing arguments please.
Code:
template <class Type>
void Array<Type>::SetElement(const Type& type_object, int index)
{
if (index >= m_size || index < 0)
{throw std::out_of_range("Out of range error in void Array<Type>::SetElement");}
m_data[index] = type_object;
}
There, it's as simple as that.
Now, the GET:
Code:
template <class Type>
const Type& Array<Type>::GetElement(int index) const
{
try
{
if (index > m_size || index < 0){ throw 1;}
}
catch (double x)
{
cout << "index incorrect, index too big or too small " << x << endl;
}
return m_data[index];
}
This is even more horrible.
1) what is funny is that this does not do what you think at all. You are throwing an "int", but catching a "double". although an int is convertible to double, catches require exact matches, and will not cast for you. So basically, you won't catch your exception.
2) Even if it did, did you notice that you are still calling "return m_data[index];". After all that, you are still doing the out of range read. Talk about useless.
3) Why did you change the range condition? if index == m_size, it is illegal.
Code:
template <class Type>
const Type& Array<Type>::GetElement(int index) const
{
if (index >= m_size || index < 0)
{throw std::out_of_range("Out of range error in void Array<Type>::GetElement");}
return m_data[index];
}
now, you can try writing your main like this:
Code:
int main()
try
{
Point *p1 = new Point (1,12);
cout << endl;
Array<Point> arr1(5);
arr1.SetElement(*p1,0);
cout << endl;
arr1.GetElement(16) ;
delete p1;
return 0;
}
catch(const std::exception& e)
{
std::cout << e.what() << std::endl;
throw;
}
----
If you read through all of this, and are still wondering what the error is, it's not very complicated. Your compiler even tells you about it if you read his warnings.
Last edited by monarch_dodra; June 18th, 2012 at 03:46 AM.
Is your question related to IO?
Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.
Why is the destructor commented out? By commenting this out, your code is automatically buggy to begin with. You allocate in the constructor and fail to delete the memory in the destructor.
We can keep going around and around with this -- you've started at least 3 threads concerning this same class, and instead of taking what was stated in the last thread (by I believe monarch_dodra), you go ahead and do the wrong things over and over again.
Start off with a properly working Array class that knows how to copy and destroy itself safely and without bugs. That was given to you in the other thread. Don't go and start doing your own thing, because evidently you are not proficient in pointers and dynamically allocated memory.
Regards,
Paul McKenzie
My deadline and amount of time and afford that I wasted on this little exercise push to me because of this I try to find more easy ways...my hands falling off((( However you right... let me try play with monarch_dodra's code...
this is miracle!!! because of your words I'm return to older thread and it takes me 5 minute to implement needed me function to
monarch_dodra's code for int class... now I'll try to for my "Point" class , let see what happen...
thank you for your scums post... Thank you that you that you don't uncaring...
regards !!!!
Last edited by oteel; June 18th, 2012 at 03:52 AM.
Re: Try to put own Class to creating by me <Template> like vector. unknow compile err
Originally Posted by oteel
My deadline and amount of time and afford that I wasted on this little exercise push to me because of this I try to find more easy ways...my hands falling off
But by just removing code, you added more bugs. You need to be more patient and figure out exactly what needs to be fixed, and not just randomly remove code just to get something to work.
Besides, whoever is going to grade your code would see the same mistakes we're seeing, especially the mistake of commenting out the destructor. Even if your code ran by luck, you would get a low grade for writing buggy code.
this is miracle!!! because of your words I'm return to older thread that it takes me 5 minute to implement needed me function to
monarch_dodra code for int class... now I'll try to for my "Point" class , let see what happen...
Please take the code I posted, take monarch_dodra's comments on this thread, and patiently put the two together to create a working program. Don't go and do your own thing because there is a deadline -- you'll only make the problem much worse.
Re: Try to put own Class to creating by me <Template> like vector. unknow compile err
Originally Posted by monarch_dodra
Code:
Please I really just want to see correction of code even without comments... Thanks in advance
Unfortunately, you should consider that what you'll find here is exactly the opposite. Nobody will straight up correct your code. On the contrary, we'll take the time to try to teach you, and hope you'll find the problem yourself. We're not here to do/correct your homework, but we can still help.
----
First: Set:
Code:
template <class Type>
void Array<Type>::SetElement(Type& type_object, int index)
{
try
{
if (index >= m_size){throw 11;}
m_data[index] = type_object;
cout << "Set Element " << type_object << endl;
}
catch (int x )
{
cout << "ERROR" << x << " ignore the set, because index of element bigger then massive size"<< endl;
}
}
What the **** is this ****? You are throwing around ints, catching them in the same method, and then squelching the error.
If the caller made a mistake, there is nothing wrong with throwing an exception. That's the callers problem, and your responsibility is to throw an something at him:
BTW: const correctness when passing arguments please.
Code:
template <class Type>
void Array<Type>::SetElement(const Type& type_object, int index)
{
if (index >= m_size || index < 0)
{throw std::out_of_range("Out of range error in void Array<Type>::SetElement");}
m_data[index] = type_object;
}
There, it's as simple as that.
Now, the GET:
Code:
template <class Type>
const Type& Array<Type>::GetElement(int index) const
{
try
{
if (index > m_size || index < 0){ throw 1;}
}
catch (double x)
{
cout << "index incorrect, index too big or too small " << x << endl;
}
return m_data[index];
}
This is even more horrible.
1) what is funny is that this does not do what you think at all. You are throwing an "int", but catching a "double". although an int is convertible to double, catches require exact matches, and will not cast for you. So basically, you won't catch your exception.
2) Even if it did, did you notice that you are still calling "return m_data[index];". After all that, you are still doing the out of range read. Talk about useless.
3) Why did you change the range condition? if index == m_size, it is illegal.
Code:
template <class Type>
const Type& Array<Type>::GetElement(int index) const
{
if (index >= m_size || index < 0)
{throw std::out_of_range("Out of range error in void Array<Type>::GetElement");}
return m_data[index];
}
now, you can try writing your main like this:
Code:
int main()
try
{
Point *p1 = new Point (1,12);
cout << endl;
Array<Point> arr1(5);
arr1.SetElement(*p1,0);
cout << endl;
arr1.GetElement(16) ;
delete p1;
return 0;
}
catch(const std::exception& e)
{
std::cout << e.what() << std::endl;
throw;
}
----
If you read through all of this, and are still wondering what the error is, it's not very complicated. Your compiler even tells you about it if you read his warnings.
Ones again Thanks you very much for your posts !!!!
I implement what you said and I I received the following errors:
1>------ Build started: Project: 42b, Configuration: Debug Win32 ------
1> main.cpp
1>c:\all my\с++\ha level 6\solution1\level6\42b\array.cpp(88): error C2317: 'try' block starting on line '81' has no catch handlers
1> c:\all my\с++\ha level 6\solution1\level6\42b\array.cpp(79) : while compiling class template member function 'void Array<Type>::SetElement(const Type &,int)'
1> with
1> [
1> Type=Point
1> ]
1> c:\all my\с++\ha level 6\solution1\level6\42b\main.cpp(14) : see reference to class template instantiation 'Array<Type>' being compiled
1> with
1> [
1> Type=Point
1> ]
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Line 79 and 88 this is open and close braces for try loop for SetElement function
last code's edition
Code:
//array.h
#ifndef Array_H
#define Array_H
template <class Type> //Remove the "=double" default parameter.
class Array
{
private:
int m_size;
Type* m_data; //m_data should be a pointer, since you want to allocate data to it
public:
Array();
Array(int new_size);
Array(const Array<Type>& ar);
~Array(); //Don't make your destructor virtual. There is no reason to do it.
const Type& Array<Type>::GetElement(int index) const;
void Array<Type>::SetElement(const Type& type_object, int index);
Array<Type>& operator=(const Array& ar); //Const correctness here.
void Swap(Array& ar);
};
//Implementation goes here
#endif
//point.h
#include "array.h"
#include <sstream>
#include <iostream>
using namespace std;
class Point
{
private:
double m_x;
double m_y;
public:
// Constructors
Point(): m_x(0), m_y(0) {};
Point(double new_x, double new_y) : m_x(new_x), m_y(new_y) {};
friend ostream& operator << (ostream& os, const Point& point)
{
return os << point.ToString();
}
std::string Point::ToString(void) const // create a string representation of a point
{
// create a string like: “Point(1.5, 3.9)”
std::ostringstream os;
os << m_x << " , " << m_y;
std::string double_string = os.str();
return "Point(" + double_string + ")";
}
};
//array.cpp
#include "Array.h"
#include <sstream>
#include <iostream>
#include <exception>
using namespace std;
#ifndef Array_CPP
#define Array_CPP
template <class Type>
Array<Type>::Array() : m_size(0), m_data(0)
{ }
template <class Type>
Array<Type>::Array(int new_size) : m_size(new_size), m_data(new Type[new_size])
{ }
template <class Type>
Array<Type>::~Array()
{
//Technically, the if is not necessary
if(m_data)
{
delete[] m_data;
m_data = 0;
}
//Not necessary either, but just to be clean
m_size = 0;
}
template <class Type>
Array<Type>::Array(const Array& ar) : m_data(0), m_size(0)
{
if(!ar.m_data) {return;}
Array tmp; //Copy construct into another temporary array, this way, if something throws, tmp will clean itself up.
//Create the array
tmp.m_data = new Type[ar.m_size];
tmp.m_size = ar.m_size;
//Copy the array elements
for(int i = 0; i < tmp.m_size; ++i)
{tmp.m_data[i] = ar.m_data[i];}
//All done! swap into this!
this->Swap(tmp);
}
template <class Type>
Array<Type>& Array<Type>::operator=(const Array& ar)
{
//Check self assign:
if(this == &ar) {return *this;}
Array<Type> copy(ar); //Create a copy of ar; If this fails, then *this will not be changed, and nothing will leak
//Succeeded creating copy. Now we can put it inside this
this->Swap(copy); //And then swap the copy into this!
return *this;
}
template <class Type>
void Array<Type>::Swap(Array& ar)
{
Type* data = m_data;
int size = m_size;
m_data = ar.m_data;
m_size = ar.m_size;
ar.m_data = data;
ar.m_size = size;
}
template <class Type>
void Array<Type>::SetElement(const Type& type_object, int index)
{
try
{
if (index >= m_size || index < 0 )
{ throw std:: out_of_range ("out of range error in void Array<Type>::SetElement");}
m_data[index] = type_object;
cout << "Set Element " << type_object << endl;
}
}
template <class Type>
const Type& Array<Type>::GetElement(int index) const
{
if (index > m_size || index < 0)
{ throw std::out_of_range ("Out of range error in void Array<Type>::GetElement");}
return m_data[index];
}
#endif //Array_CPP
//main.cpp
#include "point.h"
#include <iostream>
#include <sstream>
#include "array.cpp"
#include <exception>
using namespace std;
int main()
try
{
Point *p1 = new Point (1,12);
cout << endl;
Array<Point> arr1(5);
arr1.SetElement(*p1,0);
cout << endl;
arr1.GetElement(16) ;
delete p1;
return 0;
}
catch(const std::exception& e)
{
std::cout << e.what() << std::endl;
throw;
}
Re: Try to put own Class to creating by me <Template> like vector. unknow compile err
Probable it'll be post in style of captain obvious but if I commented out the code related this try-catch blocks in array.cpp and main.cpp then everything work fine... Finally...
ups... sorry... silly mistake I handled it
excess try in body of SetElement()
Last edited by oteel; June 18th, 2012 at 05:22 AM.
* The Best Reasons to Target Windows 8
Learn some of the best reasons why you should seriously consider bringing your Android mobile development expertise to bear on the Windows 8 platform.