Problem with exercise

Hello,

i have a problem with an exercise:

Modify the Vector class header and implementation files (Listings header and function declaration )so that the magnitude and angle are no longer stored as data components. Instead,they should be calculated on demand when the magval() and angval() methods are called.You should leave the public interface unchanged (the same public methods with the same arguments) but alter the private section, including some of the private method and the method implementations.Test the modified version with Listing, which should be left unchanged because the public interface of the Vector class is unchanged.

The header file:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

namespace VECTOR
{
    class Vector
    {
        public:
            enum Mode{RECT,POL};//rect for rectangular, pol for polar
        private:
            double x;
            double y;
            double mag;
            double ang;
            Mode mode;
            //private methods for setting values
            void set_mag();
            void set_ang();
            void set_x();
            void set_y();
        public:
            Vector();
            Vector(double n1, double n2, Mode form = RECT);
            void reset(double n1, double n2, Mode form = RECT);
            ~Vector();
            double xval () const { return x; } // report x value
            double yval () const { return y; } // report y value
            double magval() const { return mag; }
            double angval() const { return ang; }
            void polar_mode();
            void rect_mode();
            //operator overloading
            Vector operator+(const Vector & b) const;
            Vector operator-(const Vector & b) const;
            Vector operator-() const;
            Vector operator*(double n) const;
            //friends
            friend Vector operator*(double n, const Vector & a);
            friend std::ostream & operator<<(std::ostream & os, const Vector & v);
    };
} 


the declaration of the functions:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114


namespace VECTOR
{
	const double Rad_to_deg=57.2957795130823;

void Vector::set_mag()
	{mag=sqrt(x*x+y*y);}

void Vector::set_ang()
	{if (x==0.0 && y==0.0)
	ang=0.0;
	else 
	ang = atan2(y,x);
	}
	void Vector :: set_x()
	{
		x=mag*cos(ang);
	}

	void Vector :: set_y()
	{
		y=mag * sin(ang);
	}

	Vector::Vector()
	{	x=y=mag=ang=0.0;
		mode='r';}

	Vector::Vector(double n1, double n2, char form)
	{
		mode=form;
		if(form =='r')
		{	x=n1;
			y=n2;
			set_mag();
			set_ang();
		}
		else if (form =='p')
		{	mag=n1;
			ang=n2/Rad_to_deg;
			set_x();
			set_y();
		}
		else
		{
			cout<<"Incorrect 3rd argument to Vector() -- ";
			cout<<"vector set to 0\n";
			x=y=mag=ang=0.0;
			mode = 'r';}
	}
	void Vector::set(double n1, double n2, char form)
		{
mode = form;
if (form == 'r')
{
x = n1;
y = n2;
set_mag();
set_ang();
}
else if (form == 'p')
{
mag = n1;
ang = n2 / Rad_to_deg;
set_x();
set_y();
}
else
{cout << "Incorrect 3rd argument to Vector() -- ";
cout << "vector set to 0\n";
x = y = mag = ang = 0.0;
mode = 'r';}}

Vector::~Vector() // destructor
{}
void Vector::polar_mode() // set to polar mode
{mode = 'p';}
void Vector::rect_mode() // set to rectangular mode
{mode = 'r';}
// operator overloading
// add two Vectors

Vector Vector::operator+(const Vector & b) const
{return Vector(x + b.x, y + b.y);}
// subtract Vector b from a

Vector Vector::operator-(const Vector & b) const
{return Vector(x - b.x, y - b.y);}
// reverse sign of Vector

Vector Vector::operator-() const
{return Vector(-x, -y);}
// multiple vector by n

Vector Vector::operator*(double n) const
{return Vector(n * x, n * y);}
// friend methods
// multiply n by Vector a

Vector operator*(double n, const Vector & a)
{return a * n;}
// display rectangular coordinates if mode is r,
// else display polar coordinates if mode is p

std::ostream & operator<<(std::ostream & os, const Vector & v)
{if (v.mode == 'r')
os << "(x,y) = (" << v.x << ", " << v.y << ")";
else if (v.mode == 'p')
{os << "(m,a) = (" << v.mag << ", "
<< v.ang * Rad_to_deg << ")";}
else
os << "Vector object mode is invalid";
return os;}


I thought about changing the functions magval and angval, but they are in the public interface, so the task doesnt allow it.

What is the trick for this exercise?

Last edited on
Trick isn't really the right word.

See this class variable?
double mag;
Remove it.

See this function?
double magval() const { return mag; }
It won't work now because mag doesn't exist. Delete return mag; and instead write some code to calculate a value to return.

I thought about changing the functions magval and angval, but they are in the public interface, so the task doesnt allow it.

I suspect that's exactly what you're meant to do. Just don't change the name or the return type of the function.

It does seem odd to insist that the contents of the function be unchanged (and indeed, impossible, if mag is to no longer exist). Perhaps you're meant to create a private calc_mag function. Or more likely, change that set_mag function to something like:

1
2
double Vector::get_mag()
	{ return sqrt(x*x+y*y);}


and then just call if from magval.

The exercise doesn't make any sense if you're not allowed to change the function magval and are also required to remove the variable mag. How would it even compile?
Last edited on
The problem is, how can you handle with mag or angin the functions, for example in line 64 and 65?
What about a solution like the following?

Vector.h:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
// Modify the Vector class header and implementation files (Listings header 
// and function declaration )so that the magnitude and angle are no longer 
// stored as data components. Instead,they should be calculated on demand 
// when the magval() and angval() methods are called.
// You should leave the public interface unchanged (the same public methods 
// with the same arguments) but alter the private section, including some of 
// the private method and the method implementations.
// Test the modified version with Listing, which should be left unchanged 
// because the public interface of the Vector class is unchanged.
namespace VECTOR
{
    class Vector
    {
    public:
        enum Mode { RECT, POL };    // rect for rectangular, pol for polar
        Vector() = default;
        Vector(double n1, double n2, char form = 'r');
        void reset(double n1, double n2, char form = 'r');
        ~Vector() = default;
        double xval() const; // report x value
        double yval() const; // report y value
        double magval() const;
        double angval() const;
        void polar_mode();
        void rect_mode();
        //operator overloading
        Vector operator+(const Vector & b) const;
        Vector operator-(const Vector & b) const;
        Vector operator-() const;
        Vector operator*(double n) const;
        //friends
        friend Vector operator*(double n, const Vector & a);
        friend std::ostream & operator<<(std::ostream & os, const Vector & v);
    private:
        double x {};
        double y {};
        Mode mode { RECT };
        //private methods for setting values
        double set_mag() const;
        double set_ang() const;
        void set_x(double mag, double ang);
        void set_y(double mag, double ang);
    };
} // end namespace VECTOR 


Vector.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include <cmath>
#include <iostream>
#include "Vector.h"

namespace VECTOR
{ 
    constexpr double Rad_to_deg = 57.2957795130823;

    // Vector::Vector() <-- defaulted

    Vector::Vector(double n1, double n2, char form)
    { reset(n1, n2, form); }

    void Vector::reset(double n1, double n2, char form)
    {
        if(form == 'r') {
            mode = RECT;
            x = n1;
            y = n2;
            return;
        }
        if(form == 'p') {
            mode = POL;
            double mag = n1;
            double ang = n2 / Rad_to_deg;
            set_x(mag, ang);
            set_y(mag, ang);
            return;
        }
        mode = RECT;
        x = y = 0.0;
        std::cout << "Incorrect 3rd argument to Vector() -- "
                     "vector set to 0\n";
    }

    // Vector::~Vector() <-- defaulted

    double Vector::xval() const { return x; }

    double Vector::yval() const { return y; }

    double Vector::magval() const { return set_mag(); }

    double Vector::angval() const { return set_ang(); }

    void Vector::polar_mode() // set to polar mode
    { mode = POL; }

    void Vector::rect_mode() // set to rectangular mode
    {
        // This is illogical: since you don't store any more the values
        // for mag and ang, you can't calculate x and y.
        // This method should ask for new x and y values, or for new ang and 
        // mag and calculate x and y straight on.
        mode = RECT;
    }

    // operator overloading
    // add two Vectors
    Vector Vector::operator+(const Vector& b) const
    { return Vector(x + b.x, y + b.y); }    // relying on mode default value 
                                            // means facing troubles when the
                                            // interface is modified.

    // subtract Vector b from a
    Vector Vector::operator-(const Vector& b) const
    { return Vector(x - b.x, y - b.y); }

    // reverse sign of Vector
    Vector Vector::operator-() const
    { return Vector(-x, -y); }

    // multiple vector by n
    Vector Vector::operator*(double n) const
    { return Vector(n * x, n * y); }

    // friend methods
    // multiply n by Vector a
    Vector operator*(double n, const Vector& a)
    { return a * n; }

    // display rectangular coordinates if mode is r,
    // else display polar coordinates if mode is p
    std::ostream& operator<<(std::ostream& os, const Vector& v)
    {
        switch(v.mode) {
        case Vector::Mode::RECT:
            os << "(x,y) = (" << v.x << ", " << v.y << ")";
            break;
        case Vector::Mode::POL:
            os << "(m,a) = (" << v.magval() << ", "
               << v.angval() << ")";
            break;
        default:
            os << "Vector object mode is invalid";
            break;
        }
        return os;
    }

    double Vector::set_mag() const { return std::sqrt(x * x + y * y); }

    double Vector::set_ang() const
    {
        if(x == 0.0 && y == 0.0) { return  0.0; }
        else                     { return atan2(y, x); }
    }

    void Vector::set_x(double mag, double ang) { x = mag * cos(ang); }

    void Vector::set_y(double mag, double ang) { y = mag * sin(ang); }
} // end namespace VECTOR 


main.cpp:
1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include "Vector.h"

int main()
{
    VECTOR::Vector myv(5.0, 10.0);
    myv.polar_mode();
    std::cout << myv << '\n';
    return 0;
}

Thank you!
Topic archived. No new replies allowed.