Doing maths to copy constructed variables

This is a discussion on Doing maths to copy constructed variables within the C++ Programming forums, part of the General Programming Boards category; In the code below how do I go about calling both variations of each coordinate? What I want to be ...

  1. #1
    Registered User
    Join Date
    Dec 2007
    Posts
    6

    Doing maths to copy constructed variables

    In the code below how do I go about calling both variations of each coordinate?

    What I want to be able to do is:
    Have what is called a cityblock measurement on the two versions of each coordinate. This is a basic subtraction of one coordinate from the other.

    I want to have x1-x2 where x2 is the copied version of x.
    This should also happen on y and z.

    1D would do the maths on x1-x2 only, 2D would do x1-x2 and y1-y2 etc.
    They are printed out seperatley.

    The answer would be stored in an int called cityblockX for x, etc.

    I have absolutley no idea how to go about this.
    Simple steps would be wonderful.



    Also, if anyone can explain to me what exactly the bits in the code do where I have commented that I don't quite understand would be lovely.

    Code:
    #include <iostream>
    using namespace std;
    
    class Point1D 
    {
    public:
      //Initialise x_ to 0
      Point1D():x_(0){}
      
      //Give x_ whatever the value of xVal is?
      Point1D(int xVal):x_(xVal){}
    
      //Copy Constructor (gah! What does this do exactly?)
      Point1D(const Point1D &rhs):x_(rhs.x_){}
      
      //Destructor (virtual because it's the base class)
      virtual ~Point1D(){}
      
      //Print out 1D
      virtual void PrintValues()
      {
        cout << endl
                  << "Point1D values: " << endl
                  << "x= " << x_ << endl;
      }
      
      
      
      
      //Gets x from private and returns its value
      int GetX()const {return x_;}
    
      //Sets x to whatever val contains - therefore x_ is indirectly editable
      void SetX(int val){x_ = val;}
    
    private:
      //Creates x_ as a private integer
      int x_;
    };
    
    
    
    
    //Start class Point2D and inherit Point1D
    class Point2D : public Point1D 
    {
    public:
      //Set the inherited Point1D and the new Point2D to 0(?)
      Point2D():Point1D(0){}
      
      //Crazy copy constructor stuff (really need to find out what this does)
      Point2D(int yVal):Point1D(0),y_(yVal){}
      Point2D(int xVal,int yVal):Point1D(xVal),y_(yVal){}
    
      //Copy Constructor (what does this do?)
      Point2D(const Point1D &rhs):Point1D(rhs.GetX()),y_(0){}
      Point2D(const Point2D &rhs):Point1D(rhs.GetX()),y_(rhs.y_){}
    
      //Deconstructor (virtual because it's a base class to 3D?)
      virtual ~Point2D(){}
      
      //Print out values from 1D (using GetX) and 2D
      virtual void PrintValues()
      {
    
        cout << endl
                  << "Point2D values: " << endl
                  << "x= " << GetX() << endl
                  << "y= " << y_ << endl;
      }
      
      //Gets y from private and returns its value
      int GetY()const {return y_;}
      //Sets y to whatever val contains - therefore y_ is indirectly editable
      void SetY(int val){y_ = val;}
    
    private:
      //Creates y_ as a private integer
      int y_;
    };
    
    
    
    
    //Start class Point3D and inherit Point2D (and therefore Point1D)
    class Point3D : public Point2D 
    {
    public:
      //Set the inherited Point2D, and the new Point3D to 0?
      Point3D():Point2D(0){}
      
      //Really need to find out what this does(?)
      Point3D(int zVal):Point2D(0),z_(zVal){}
      Point3D(int xVal,int yVal, int zVal):Point2D(xVal,yVal),z_(zVal){}
    
      //Copy Constructor (what does this do exactly?)
      Point3D(const Point1D &rhs):Point2D(rhs.GetX(),0),z_(0){}
      Point3D(const Point2D &rhs):Point2D(rhs.GetX(),rhs.GetY()),z_(0){}
      Point3D(const Point3D &rhs):Point2D(rhs.GetX(),rhs.GetY()),z_(rhs.z_){}
    
      //Destructor
      ~Point3D(){}
      
      //Print 3D Values (including 1D and 2D)
      void PrintValues()
      {
        cout << endl
                  << "Point3D values: " << endl
                  << "x= " << GetX() << endl
                  << "y= " << GetY() << endl
                  << "z= " << z_ << endl;
      }
    
      //Gets z from private and returns its value
      int GetZ()const {return z_;}
      //Sets z to whatever val contains - therefore z_ is indirectly editable
      void SetZ(int val){z_ = val;}
    
    private:
      //Creates z_ as a private integer
      int z_;
    };
    
     
          
    //Starts main
    int main() {
    
    int dimension;
    cout<<"Please press 1 for 1D, 2 for 2D, 3 for 3D and press Return\n";
    cin>>dimension;
      
    if (dimension == 1){
       //Setting and printing
       Point1D point1D(1);
       point1D.PrintValues();
       //Changing the copies and printing
       Point1D copyOfPoint1D(2);
       copyOfPoint1D.PrintValues();
       
    
       system("pause");
    }
                  
       else if (dimension == 2){
          //Setting and printing
          Point2D point2D(2,2);
          point2D.PrintValues();
          //Changing the copies and printing
          Point1D point1D(1);
          Point2D point2DFromPoint1D(point1D);
          point2DFromPoint1D.SetY(1);
          point2DFromPoint1D.PrintValues();
          system("pause");
       }
          else if (dimension == 3){
            //Setting and printing
            Point3D point3D(3,3,3);
            point3D.PrintValues();
            //Changing the copies and printing
            Point1D point1D(1);
            Point2D point2DFromPoint1D(point1D);
            point2DFromPoint1D.SetY(2);
            Point3D point3DFromPoint2D(point2DFromPoint1D);
            point3DFromPoint2D.SetZ(3);
            point3DFromPoint2D.PrintValues();
            system("pause");
          }   
    
    //If the user puts anything other than 1, 2 or 3 print an error and restart main
    else { 
         cout<<"Error\n";
       system("pause");
    }
    
    
       return 0;
    }

  2. #2
    Registered User
    Join Date
    Jan 2005
    Posts
    7,319
    >> //Copy Constructor (gah! What does this do exactly?)

    A copy constructor is a special kind of constructor that creates an object with values copied from another object. So in the case of the Point1D class, the copy constructor takes a reference to a different Point1D object. The constructor then initializes its private member data (n this case x_) with the data in the other object.

    If you don't make a copy constructor, then the compiler will generate one for you. The compiler generated one will initialize each member variable with the data in the corresponding member variable of the other object. Notice that this is exactly what your version does. That means that you can remove your copy constructors and the code would execute in exactly the same way.

    It is actually a better idea to remove those copy constructors for that reason. If you type them out yourself, you might make a mistake. But if you let the compiler generate them for you, then you can be pretty sure that the compiler's version is correct.

    The only time you need to write your own copy constructor is if the member variables in your class don't copy themselves the way you want them to. An example is a handle to a file. Let's say your class opens a file for reading in its constructor and closes it in the destructor. It saves a handle to the file so it knows how to close it. If you copy that class the normal way, then both the original object and the copy will contain the same handle to the file. Then when one object is destroyed it will close the file but the other object will still think it is open and might try to use it. This would be bad. The solution might be to open a separate file handle for each copy, so that if one object closes its handle the other object has its own handle to still be allowed to read from.

    In real code, you should be using pre-existing classes that do this type of thing for you, so you almost never need to write your own copy constructor.


    Also note that the copy assignment operator (e.g. Point1D operator=(const Point1D & rhs)) follows the same rules and restrictions regarding compiler generated versions and when it is necessary to write your own. A general rule is that if you need a copy constructor then you need a copy assignment operator (and usually if you need a destructor that does real work then you need to write your own versions of the copy functions also).

  3. #3
    Registered User
    Join Date
    Jan 2005
    Posts
    7,319
    >> I have absolutley no idea how to go about this.
    Is it supposed to be an operator-, or just a member function of the classes?

  4. #4
    Registered User
    Join Date
    Jan 2007
    Location
    Euless, TX
    Posts
    144
    I think you may be causing yourself to do a lot more typing than you need to. Class 'Point1D' is, to me, meaningless by itself --- nothing more than a value on the X-axis really. Why not just create a 'Point3D' to use everywhere? If 'Z' = 0, then you have a point on a 2D plane, in X/Y coordinates. At least this way you don't have to carry around a whole bunch of baggage in the form of the other two classes. Or am I missing something in what you are really trying to do here?

  5. #5
    Registered User
    Join Date
    Dec 2007
    Posts
    6
    Quote Originally Posted by kcpilot View Post
    I think you may be causing yourself to do a lot more typing than you need to. Class 'Point1D' is, to me, meaningless by itself --- nothing more than a value on the X-axis really. Why not just create a 'Point3D' to use everywhere? If 'Z' = 0, then you have a point on a 2D plane, in X/Y coordinates. At least this way you don't have to carry around a whole bunch of baggage in the form of the other two classes. Or am I missing something in what you are really trying to do here?
    kcpilot Basically, I have this example code from a book, and I am embellishing it with more interesting things to learn C++ with.

    I'd like to keep the classes the way they are, but wish to add the functionality I mentioned above.


    Daved thank you. That is a handy explanation.

    >> I have absolutely no idea how to go about this.
    Is it supposed to be an operator-, or just a member function of the classes?
    I would like 1D, 2D, 3D to each have their own member function called cityblockx, cityblocky for example. This would contain the worked out value.

    However, I am looking to (after this) also include another measurement:

    PythagDistance which would take the coordinates and work out the straight line distance between the points.
    So I'm presuming the two coordinates need to be stored somewhere to do this (but I have no idea, again).


    Thank you for your help so far, any more is greatly appreciated.

    Code is even better, mind.
    Tell you what, if you want I could wing 5 (worth $10 if you're a yank) your way via paypal if you'd like for any code help from here.

    Can't just ask you to code for me for free, that's rude

  6. #6
    Registered User
    Join Date
    Jan 2005
    Posts
    7,319
    Personally, I wouldn't do it for money, and I'm not sure why you'd want this coded for money unless it was an assignment, and that's not something that is done here.

    However, I can continue to give you advice on how to accomplish the task.

    I have a question about these functions. It seems to me that it would make sense to have one function called cityblock that is implemented in each class, kind of like the PrintValues function. Each class would determine the distance between the current point and a point passed to the function depending on whether it is a 1, 2 or 3D point.

    You could also make this a non-member function, which might be better design in general but not what is being asked for in the assignment.

    Are you supposed to be able to provide the distance between a 1D and 2D point, or 2D and 3D, or 1D and 3D?

  7. #7
    Registered User
    Join Date
    Dec 2007
    Posts
    6
    Quote Originally Posted by Daved View Post
    Personally, I wouldn't do it for money, and I'm not sure why you'd want this coded for money unless it was an assignment, and that's not something that is done here.

    However, I can continue to give you advice on how to accomplish the task.

    I have a question about these functions. It seems to me that it would make sense to have one function called cityblock that is implemented in each class, kind of like the PrintValues function. Each class would determine the distance between the current point and a point passed to the function depending on whether it is a 1, 2 or 3D point.

    You could also make this a non-member function, which might be better design in general but not what is being asked for in the assignment.

    Are you supposed to be able to provide the distance between a 1D and 2D point, or 2D and 3D, or 1D and 3D?
    I am trying to get the distance between point 1D (x) and the copy constructed 1D(x) for a start.

    If the user is dealing with 2D then it does the calculation on x1-x2 and also y1-y2.

    and so on.

    Thanks for all the help thus far.

  8. #8
    Registered User
    Join Date
    Jan 2005
    Posts
    7,319
    So do you agree that a virtual method called cityblock (or whatever) that is implemented in each class makes sense? If so, then go ahead and add it. Use the PrintValues() method as an example.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How to copy a C struct to a C++ class?
    By Ptbamboo in forum C++ Programming
    Replies: 1
    Last Post: 02-21-2009, 01:11 PM
  2. Replies: 5
    Last Post: 12-09-2008, 01:18 PM
  3. Father and Son Variables
    By khdani in forum Linux Programming
    Replies: 3
    Last Post: 11-28-2008, 05:42 PM
  4. Copying constant amount of data
    By TriKri in forum C++ Programming
    Replies: 16
    Last Post: 07-12-2008, 06:32 AM
  5. Copy Constructor Help
    By Jubba in forum C++ Programming
    Replies: 2
    Last Post: 11-07-2001, 10:15 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21