1

Here is the problem I have, please don't beat me up if I don't explain it well or the code is of bad quality - I have only done about 2 weeks of C++ so far.

Explanation: I would like to build a structure (a structure might not be the best decision but I have to start somewhere) that will contain coordinates (x and y only) of a set of points (let's call the set an arc), set id (and possibly other fields). Each set (arc) can contain various numbers of points. I have implemented each point in the set (arc) as the class, then my arc structure contains various instanses of this class in a vector (along with other stuff).

Example of an arc structure:

Struc1:

Id (int) 1

xY (vector) (0;0) (1;1) (2;2)

Struc2:

Id (int) 2

xY (vector) (1;1) (4;4)

Problem: I can't figure out how to access elements within my arc structure: for example if I need to access the coordinates of the second point in the struc with Id 1, I would want Struc1.xY[1], however this doesn't work as my code (below) stands. I have found this post that explains how one could print values inside the struct, but I will need to access these elements to (later on) conditionally edit those coordinates. How can this be impemented?

My attempt: (EDITED)

#include <cmath>
#include <vector>
#include <cstdlib> 
#include <stdio.h>
#include <iostream>

using namespace std;

class Point
  {
  public:
      Point();
      ~Point(){ }

      void setX (int pointX) {x = pointX; }
      void setY (int pointY) {y = pointY; }
      int getX() { return x; }
      int getY() { return y; }

  private:
      int x;
      int y;
  }; 

Point::Point()
    {
        x = 0;
    y = 0;
    }

struct arc {
  int id;
  vector<Point> xY;
};

int main(){

  arc arcStruc;
  vector<Point> pointClassVector;
  int Id;
  int X;
  int Y;
  // other fields go here

  arc *a;

  int m = 2; // Just create two arcs for now
  int k = 3; // each with three points in it
  for (int n=0; n<m; n++){    
    a = new arc;
    Id = n+1;
    arcStruc.id = Id;
    Point pt;
    for (int j=0; j<k; j++){            
      X = n-1;
      Y = n+1;      
      pt.setX(X);
      pt.setY(Y);
      arcStruc.xY.push_back(pt);

    }
  }

for (vector<Point>::iterator it = arcStruc.xY.begin(); it != arcStruc.xY.end(); ++it)
  {
    cout << arcStruc.id.at(it);
    cout << arcStruc.xY.at(it);
  }

  delete a;  
  return 0;
}
Community
  • 1
  • 1
Aina
  • 653
  • 2
  • 9
  • 22

1 Answers1

1

A couple of suggestions:

  • Don't bother with the separate pointClassVector, just create and instead the Point objects straight into arcStruc.xY by using arcStruc.xY.push_back(). The line arcStruc.xY = pointClassVector triggers a copy of the whole vector, that's a bit of a waste of CPU cycles.
  • There is absolutely no need to try and create a Point object on the heap, all that does is add complexity. Just use Point pt; and call the set functions on it - although I personally would do away with the set functions altogether and manipulate the data in Point directly, there is no need for the getters/setters and they don't buy you anything. If this was my code, I'd write the point constructor to take x and y as parameters, that saves you an awful lot of unnecessary code. You also don't need to provide an implementation for the destructor, the compiler generated one is fine.

If you want to iterate through the vector, you should probably use iterators instead of attempting to index into the container. Either way, you can access arcStruc.xY to get its size and then access the elements individually using the [] operator or using iterators, like so:

 for (vector<Point>::iterator it = arcStruc.xY.begin(); it != arcStruc.xY.end(), ++it)
 {
    ... do something with it here, it can be derefernced to get at the Point structure ...
 }
Timo Geusch
  • 24,095
  • 5
  • 52
  • 70
  • do you mean something like that (see my edited solution?). As it stands now it fails on `arcStruc.xY.push_back(pt.getX());` of course, but I don't understand from your answer how you can use `arcStruc.xY.push_back()`. – Aina Dec 17 '12 at 04:05
  • You want to use arcStruc.xY.push_back(pt) as you want to add the whole Point object to the vector, not part of it. – Timo Geusch Dec 17 '12 at 14:37
  • thanks so much for your time, I didn't know you could put anything but one value inside the push_back(). Last question: how do I iterate through the struc? In my code above (edited again) I have added in the loop `cout << arcStruc.xY.at(it);` but it throws an error. I have also tried `cout << arcStruc.xY[it];` but it also threw an error, what is the correct way to do this? – Aina Dec 17 '12 at 22:07
  • You're working at the wrong level of indirection. The iterator already points to the `Point` element inside the vector, so you'd use something like `cout << *it`, assuming that you have the appropriate `operator<<` defined for `Point`. – Timo Geusch Dec 17 '12 at 22:10
  • thanks, which operator would I need to define if I wanted to overwrite the value inside the struc element? Say something like (inside of the loop) `*it = myNewValue;` – Aina Dec 17 '12 at 23:22
  • For your points structure, you don't need to define the copy constructor and assignment operators (which you'd normally have to create in a case like this) as the compiler generated ones should do exactly what you want. – Timo Geusch Dec 17 '12 at 23:30
  • I still don't undestand how it is done because `*it = myNewValue;` only throws errors, I guess I'll have to start from scratch and find another, more transparent way to implement it but I will leave you in piece. – Aina Dec 17 '12 at 23:37
  • The question is tagged c++11, you can use the new for loop – balki Dec 18 '12 at 13:50