0

I had this question on a test about a month ago and I still can't seem to understand it completely and quite frankly it's driving me crazy. I will include the question at the bottom. But, it's asking to create a single parameter constructor that creates a new "Vector" (the name of the class) which is the sum of two others. The vector class I made has a function set/get x and set/get y. My hang up is I can't seem to figure out how to make a function that adds the two x's and y's together from vector and vector1 to create a new Vector...call it vector2. I'll include everything I got so far. Thanks to anyone willing to make it through the wall of text as confusing as it must be haha.

Write a class Vertor with the following properties and place the class in a separate header file :

Add member function with a single parameter of another vector and returns a new vector that is the sum of the two (to add vectors you sum the components, for example, Cx = Ax + Bx and Cy = Ay + By).

Write a program that includes the Vector header file, constructs two different vectors and demonstrates the magnitude, angle, and add functions.

Data Members
vector
x component
y component
Member Functions
Set and Get functions for all data members
Magnitude member function
Angle member function (angle = inverse tangent(y / x))

ps I hope I am not doing anything wrong by uploading this and asking I have waited this entire time because I didn't want to break some sort of rule in the community....that I am honestly desperate to become a part of. I've dreamed of doing this my whole life and finally....ahh i digress sorry thanks guys

Oh...my code

#include "Vertor.h"

#include <iostream>

int main()
{

    // creates a vector class
    Vector vector;

    vector.setXcom(4); // sets X
    vector.setYcom(12); // sets Y

    Vector vector1; // Creates another vector

    vector1.setXcom(3);
    vector1.setYcom(52);

    Vector vector2; // constructs another vector that returns the sum of two other vectors

    cout << vector.getXcom() << endl;
    cout << vector.getYcom() << endl;

    cout << vector.getMag() << endl;
    cout << vector.getAng() << endl;

    cout << vector1.getXcom() << endl;
    cout << vector1.getYcom() << endl;

    cout << vector1.getMag() << endl;
    cout << vector1.getAng() << endl;
}

#include<iostream> 
using namespace std;

// initalize variables
double xcomponent, ycomponent;
double ans, anns, annns;
class Vector // creates Vector class
    {
public:
    void setXcom(double x) // setX function
    {
        xcomponent = x;
    }

    void setYcom(double y) // setY function
    {
        ycomponent = y;
    }

    double getXcom() // getX function
    {
        return xcomponent;
    }

    double getYcom() // getY function
    {
        return ycomponent;
    }

    double getMag() // get magnitude function
    {
        double ans = sqrt((xcomponent * xcomponent) + (ycomponent * ycomponent));
        return ans;
    }

    double getAng() // get angle function
    {
        double annns = atan(xcomponent / ycomponent);
        return annns;
    }
    // setnewvec function to make a new vector from two others
    void setNewVec(int a, int b)
    {
        xcomponent = a;
        ycomponent = b;
    }
    // NOT SURE
    Vector getNewVec(int a, int b)
    {
        return a + a;
        return b + b;
    }
};
Sneftel
  • 40,271
  • 12
  • 71
  • 104
  • 4
    your class should have some members instead of using globals – 463035818_is_not_an_ai Nov 06 '20 at 21:20
  • such as? sorry, it's still pretty new to me, what's the difference? It's not in the header? –  Nov 06 '20 at 21:29
  • 1
    it seems like the question your are asking, while not too advanced, is still several steps to far for you. Don't skip the early chapters of your [c++ book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). If you don't understand that comment, an answer wont help you as well – 463035818_is_not_an_ai Nov 06 '20 at 21:31
  • The difference is fundamental. By putting all variables global, you can only have a single instance of the class `vector`. As soon as you have two or more, things get crazy, because all vectors... share the same values. – prapin Nov 06 '20 at 21:31
  • The question would be better focused if you dropped all mention of the magnitude and angle functions. Focus on just what you want help with (the `getNewVec` function?). – JaMiT Nov 06 '20 at 22:39
  • @JaMiT Sorry, I'm gonna fix this in a moment. First time rolling back and I though it's gonna only do the specific edit, not all that were done after it. – Piotr Siupa Nov 06 '20 at 22:42
  • 4
    Please, don't edit the question to apply the solutions from the answers to it. Future readers won't understand what the answers are about if the code in question don't have the described problems anymore. – Piotr Siupa Nov 06 '20 at 22:43

2 Answers2

3

So you have an absolutely fundamental misunderstanding or gap in your knowledge about how objects work, and this task will be impossible until you sort that out.

To illustrate here's a simpler example written in the style of your code above. I'll follow that with the same example written as it should be. This example is a simple Person class which has an age 'component'.

int age;

class Person
{
public:
    void setAge(int a) { age = a; }
    int getAge() { return age; }
};

int main()
{
    Person fred;
    fred.setAge(22);
    Person mary;
    mary.setAge(33);
    cout << "Fred is " << fred.getAge() << " and Mary is " << mary.getAge() << endl;
}

If you run this program the output will be Fred is 33 and Mary is 33. Both the people have the same age even though you set them as different in the program.

The problem is that although this program has two people it only has one age. So it's literally impossible for the two people to have different ages.

Here's the program written correctly. The crucial difference is that the age variable is inside the class. This means that each Person object gets it's own age.

class Person
{
public:
    void setAge(int a) { age = a; }
    int getAge() { return age; }
private:
    int age;
};

int main()
{
    Person fred;
    fred.setAge(22);
    Person mary;
    mary.setAge(33);
    cout << "Fred is " << fred.getAge() << " and Mary is " << mary.getAge() << endl;
}

Now the output is Fred is 22 and Mary is 33 as it should be.

john
  • 85,011
  • 4
  • 57
  • 81
  • Okay, I follow you there. Thank you very much and I completely agree with what you said about this being crucial for me to continue learning I have to get the fundamentals. Object oriented this is an object; sems like a big deal. So, I should move my variables listed first to the private class? I didn't understand that before. –  Nov 06 '20 at 21:46
  • @BlattFybull If I'm understanding your assignment correctly, the `Vector` class needs `x` and `y` variables only (that's what a vector is after all). The magnitude and angle values should be *calculated* from the `x` and `y`, so you don't need variables for those, but you do need methods that do those calculations (using the normal math formulae). – john Nov 06 '20 at 21:53
  • @john They should be calculated from `x` and `y` but they can also be stored in the object to save on calculation when they are needed multiple times. This is a very common trade off in programming: memory vs speed. They can be calculated only in setters (and constructor if there is any). – Piotr Siupa Nov 06 '20 at 22:37
1

First thing you need to do, is to move xcomponent and ycomponent to inside the object. Right now they are global variables which means they share values in all objects you create (and outside object too).

I'm gonna assume you've learned about structures before moving to objects. It's pretty hard to understand object without knowing structures first.

Structures and classes are very similar. They both are containers for variables. Classes are a little more advanced version that usually hides the raw data and instead provides member functions (sometimes called methods) that allow to manipulate the data inside in a more convenient way.

Anyway, when you create a new object of a class, you create it with a new copy all member variables (fields) inside. This way, they can have different values for each object.

Your code is pretty easy to fix in that regard. Just move definition of these variables inside your class.

Old code:

double xcomponent, ycomponent;
double ans, anns, annns;
class Vector // creates Vector class
{
public:
   //...
};

New code:

class Vector // creates Vector class
{
    double xcomponent, ycomponent;
    double ans, anns, annns;
public:
   //...
};

Now we can work on the return value.

Your return value of getNewVec is all right. You've declared that you want to return an object of type Vector and this is exactly what you want. However, the function should also take a single vector as an argument. Right now you have tho arguments int a and int b, none of which is a Vector. We need to change that to Vector otherVector to do what your assignment said.

The call of the function looks like this: someVector.getNewVec(someOtherVector). When it runs, you have two vectors accessible inside of it. The first of them is the one on which the function was called. You have direct access to its fields. The second one is of course the argument otherVector. You can access its fields through its member functions. (Or you can access directly its private fields because you're in a member function of its class.)

Now you need to construct the new vector. The simplest way is to just create it and assign the values one by one:

Vector getNewVec(Vector otherVector)
{
    Vector newVector;
    newVector.setXcom(xcomponent + otherVector.getXcom());
    newVector.setYcom(ycomponent + otherVector.getYcom());
    return newVector;
}

or:

Vector getNewVec(Vector otherVector)
{
    Vector newVector;
    newVector.setXcom(xcomponent + otherVector.xcomponent);
    newVector.setYcom(ycomponent + otherVector.ycomponent);
    return newVector;
}

or if you really want:

Vector getNewVec(Vector otherVector)
{
    Vector newVector;
    newVector.setXcom(this->getXcom() + otherVector.getXcom());
    newVector.setYcom(this->getYcom() + otherVector.getYcom());
    return newVector;
}

(this is a pointer the object your inside of. You have access to it from each member function.)

I recommend the second option.


Some additional stuff you can read about if your interested... (I'm not gonna go into any details here.)

  1. Constructors You can have a special member function that is called when object it's created that is supposed to set initial values to the fields. It is written similar to a function, except is doesn't have a return value and it's name is always the same as the name of the class.
Vector(int x, int y)
{
    xcomponent = x;
    ycomponent = y;
}

That allows to create an abject and assign the values in one line so instead of:

Vector newVector;
newVector.setXcom(12);
newVector.setYcom(42);

you can have:

Vector newVector(12, 42);

You can have more than one constructor with different list of arguments.

  1. You can create an operator instead of a normal function. An operator is a function with specific name and arguments that can be called similarly to built-in mathematical operations. Operator for addition looks like this:
Vector operator+(Vector otherVector)
//the body is the same as getNewVec

You could call it like a normal member function:

someVector.operator+(someOtherVector)

but a better way of writing it is:

someVector + someOtherVector
Piotr Siupa
  • 3,929
  • 2
  • 29
  • 65
  • THANK YOU! Okay, that's definitely a lot, but it's great to have it explained again. This can go into my source code instead of the header? Is that the difference between gloabal/member? Or is global vs member functions the public/private location. Thank you so much for all of your help. –  Nov 06 '20 at 21:55
  • Okay, I know it doesn't go in my source code, I got a little confused looking at two different things. –  Nov 06 '20 at 21:57
  • @BlattFybull `private` members can be used only by member functions of the class. `public` is accessible to everyone. The default in `class`, unlike in `struct` is `private`. That's why you need `public:` access modifier. – Piotr Siupa Nov 06 '20 at 22:03
  • I thought that it had to take two different existing vectors like my vector and vector 1 that I have set x and y for both. Then add the x's and add the y's and then those are the values of x and y for the new one that it creates. –  Nov 06 '20 at 22:21
  • @BlattFybull OK, I need to stop writing new things to the answer. This is getting to long. BTW, I didn't test any of that but it should be mostly all right. – Piotr Siupa Nov 06 '20 at 22:22
  • Oh, I don't mind at all lol, thanks again I will take all the help I can get. –  Nov 06 '20 at 22:25
  • @BlattFybull You could just write a normal non-member function that takes 2 arguments but member functions are usually the best way to do such things. It's just clearer to have all operation on the objects explicitly linked to the class. You could also make a `static` member function which is roughly equivalent to that, except it has access to private members. I would recommend normal member. This is the most common convention. – Piotr Siupa Nov 06 '20 at 22:26
  • @BlattFybull Yeah, maybe, but Stack Overflow answers are directed to every person with similar problem, not just the OP. (Although, It kinda doubtful there will another person with this exact problem.) I don't want to stretch the rules too far though. You can always ask another question or just search for an existing one. (I wanted to write about passing arguments though constant reference but I've resigned because it's more advanced stuff) One last thing. The way to say "thanks" here is to upvote/accept/both the answer. I'm not forcing you to anything, just informing because you're new here. – Piotr Siupa Nov 06 '20 at 22:31