[c++] help with sub-vector

05/19/2014 14:28 Hikarim#1
Well, i have a vector that stores objects of my class named 'Tools':
vercotr<Tools>myvect

that has lets say 5 objects saved in it... But now i want to make a method that makes a subvector from lets say 2nd (start) to 4th (end/finish) element in myvect and returns that newly created subvector.
returnSubvect(2,4); that is returning: subvect

Can anyone explain me how to do this? -Was strugling with this for some time now, but i cant get it to work.
05/19/2014 16:46 Schlüsselbein#2
std::copy/move or return std::vector(iterator1,iterator2).
05/19/2014 18:38 Hikarim#3
I did i like this, but it kinda loops and times out when i try to run..
Code:
vector<Tools> retrnSect(int start, int end){
		vector<Tools>subvect;
		for(int i=0; i<(end-start); i++){
			int x=start;
			subvect[x]=myvector[x];
			x++;
		}
		return subvect;
}
My toughts behind this was: i calculate the starting position and the endpostion and insert those elements from old vector (myvector) to the new one (subvect).
The thing compiles fine, but when i run it, it loops and breaks...
You mind checking what i am doing wrong?
05/19/2014 18:57 Delinquenz#4
Avoid using the [] - it's not good practice. Instead try using std::vector::at(). Schlüsselbein talked about iterators. - why are you using random access? It's really slow if you compare it with iterators. In my opinion iterators also are easier to understand.
05/19/2014 19:22 Hikarim#5
Quote:
Originally Posted by Delinquenz View Post
Avoid using the [] - it's not good practice. Instead try using std::vector::at(). Schlüsselbein talked about iterators. - why are you using random access? It's really slow if you compare it with iterators. In my opinion iterators also are easier to understand.
Didn't know that, because im just learning :) and i missed last weeks lesson at the school, because i was sick, so now im trying to catch up :) Thanks for the tips.

I tryed with .at() its basically the same as [], but the problem is that when i try to run the program, it collapses at the point when i call the method 'test0801.exe has stopped working' im using eclipse btw.

This is my whole project:
Code:
#include <iostream>
#include <vector>
#include <sstream>

using namespace std;
static int counter=0;

class Tools{
	protected:
		string title;
		int price;
	public:
		Tools(){title=""; price=0;}
		Tools(string title1, int price1){price=price1; title=title1;}
		~Tools(){}
		string toString()const{
			std::stringstream b;
			b << "title: " << title << ", price: " << price;
			return b.str();
		}
};

class Table: Tools{
	public:
	string name;
	int id;
	vector<Tools>myvect;
	public:
	Table(){name=""; id=counter; counter++;}
	Table(string name1, int id1){name=name1; id=id1; counter++;}
	~Table(){myvect.clear();}

	void push(Tools x){
		myvect.push_back(x);
	}
	Tools pop(){
		myvect.pop_back();
		return myvect.back();
	}
	bool delX(int index){
		int x=myvect.size();
		myvect.erase(myvect.begin() + index);
		if(myvect.size()<x){
			return true;
		}
		else{
			return false;
		}
	}
	Tools getX(int index){
		return myvect.at(index);
	}

	int size(){
		return myvect.size();
	}

	string toString()const{
		std::stringstream ss;
		ss << "name: " << name << ", id: " << id << Tools::toString();
		return ss.str();
	}


	void prntout(){
		for(int i=0; i<myvect.size(); i++){
			cout << "name: " << name << ", Id: " << id << ", ";
			cout << myvect[i].toString();
			cout << endl;
		}

	}

	vector<Tools> rtrnSect(int start, int end){
		vector<Tools>subvect;
		for(int i=0; i<(end-start); i++){
			int x=start;
			subvect.at(i)=myvect.at(x);
			x++;
		}
		return subvect;


	}
};


int main() {
	cout << "test0001" << endl;

	Table* t1=new Table("Table1", counter);
	cout << "Num of objects Table:" << counter << endl;
	Tools* c1=new Tools("Com1",300);
	Tools* c2=new Tools("Com2",400);
	Tools* c3=new Tools("Com3",200);

	t1->push(*c1);
	t1->push(*c2);
	t1->push(*c3);
	t1->prntout();

	cout << "---------------" << endl;
	t1->pop();
	t1->prntout();

	cout << "---------------" << endl;
	t1->push(*c3);
	Tools* c4=new Tools("Com4",550);
	t1->push(*c4);
	t1->prntout();
	cout << "---------------" << endl;
	//t1->delX(2);
	if(t1->delX(3)==true){
		cout << "Deleted" << endl;
	}
	else{
		cout << "Not deleted" << endl;
	}
	t1->prntout();

	cout << "---------------" << endl;
	cout << "Size: " << t1->size() << endl;

	cout << "---------------" << endl;
	Table* t3=new Table("Table3", counter);
	cout << "Num of objects Table:" << counter << endl;
	Tools* c5=new Tools("Com5",300);
	Tools* c6=new Tools("Com6",400);
	Tools* c7=new Tools("Com7",200);
	t3->push(*c1);
	t3->push(*c2);
	t3->push(*c3);
	t3->push(*c4);
	t3->push(*c5);
	t3->push(*c6);
	t3->push(*c7);
	t3->prntout();


	return 0;
}
05/19/2014 19:26 Delinquenz#6
Why do you allocate memory with new?

Instead of this
Code:
	Table* t1=new Table("Table1", counter);
you can write
Code:
	Table t1("Table1", counter);
this.

If you want to continue using new you have to delete everything. That might not be your problem but it's important to know this.

On the other way ideone.com has [Only registered and activated users can see links. Click Here To Register...] with your code.

I am not sure if this line
Code:
class Table: Tools{
makes that what you want.
05/19/2014 19:45 Hikarim#7
I am not sure if this line
Code:
class Table: Tools{
makes that what you want.[/QUOTE]
Ups, my tipo, should be class Table: public Tools... (using inheritance..)

I'm using new to allocate memory, because the school wants me to make my objects dynamically... i know i have to delete them but i didnt get to that part as i have other bugs atm...

it isnt anything wrong because i removed the parth when i try to call the method rtrnSect that has to reterun me a new vector that contains a sub region of my original vector....
am i calling the method wrong?
Code:
t3->rtrnSect(2,4);
gives me this: "This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
terminate called after throwing an instance of 'std::out_of_range'
what(): vector::_M_range_check"
05/20/2014 13:53 Delinquenz#8
Why should your Table class inherit from your Tools class when it stores them? I can't follow your logic :S In my opinion this is completely wrong, but it has nothing to do with your error. Anyway, better fix this issue.

If your application throws a std:: out_of_range exception you tried to get access to entries which the vector doesn't have. You should check the size of the sector first with the std::vector<T>::size() method to avoid such logical errors. That's the advantage of std::vector::at() since it throws exceptions if you try to access entries which don't exist instead of aborting with a dubious memory error.
05/22/2014 03:13 davydavekk#9
Here is an example with std::vector<int>, I'll let you modify it so it can fit your needs.

Code:
std::vector<int> subVector(const std::vector<int>& vec, int beg, int end)
{
	end++; // you can remove that if you don't want the element at index "end" to be included
	if (end <= vec.size()) // size check
	{
		std::vector<int> subVec; 
		std::copy(vec.cbegin() + beg, vec.cbegin() + end, std::back_inserter(subVec));
		/* std::back_inserter is an iterator that calls push_back() to insert elements at the end of std containers */
		return subVec;
	}
	else
		return std::vector<int>(); // returns an empty vector
}
Example :
Code:
std::vector<int> vec = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	
	std::vector<int>& v2 = subVector(vec, 0, 2); // remember that vectors are 0-indexed
	for (auto it = v2.cbegin(); it != v2.cend(); it++)
	{
		std::cout << *it << ' '; // prints 1 2 3
	}
	std::cout << std::endl;
By the way, your OOP design is horrible.
-If your class Table needs to access Tools' private members, make it a friend class.
-Don't use dynamic memory allocation if you don't know how it works ... here you are leaking* every single object you allocated, that's not good.

leaking : When an object is somewhere on the heap, but you don't have any valid pointer to it. (which means that you can't deallocate it)

Good luck ;)