-2

This is an example of the composition of classes. But my code doesn't show a correct answer. This program must calculate the length of the line segment in the coordinates of the two ends of the line segment! I don't know what to do in the main function. this code consists of two classes.

#include <cmath>
#include <iostream>
using namespace std;

class point {
 private:
  float x;
  float y;

 public:
  void setpoint(float abscissa, float ordinate) {
    x = abscissa;
    y = ordinate;
  }
  float getx() { return x; }

  float gety() { return y; }
};

class LineSegment {
 public:
  float length() {
    result = sqrt(pow(a.getx() - b.getx(), 2) + pow(a.gety() - b.gety(), 2));
    return result;
  }

  void displayMessage() { cout << result; }

 private:
  float result;
  point a;
  point b;
};

int main() {
  point a;
  float q, s;
  cout << "Enter two numbers for first point:\n";
  cin >> q >> s;
  a.setpoint(q, s);
  point b;
  float e, r;
  cout << "Enter two numbers for second point:\n";
  cin >> e >> r;
  a.getx();
  a.gety();
  LineSegment pt;
  pt.length();
  pt.displayMessage();

  return 0;
}

enter image description here

  • 1
    What the result are you expecting and what the final result? Did you test it? – devs121 Apr 27 '21 at 18:52
  • 1
    Show expected output and real output maybe? Show example input data? – JohnkaS Apr 27 '21 at 18:52
  • I believe your progams answers are correct, it's you who's asking the wrong questions. – πάντα ῥεῖ Apr 27 '21 at 18:57
  • 1
    On the one hand, yes the question isn't really about composition at all. On the other, the program's answers are nowhere in the vicinity of correct, nor can they ever be due to the issues in the code. – sweenish Apr 27 '21 at 19:10

3 Answers3

0

The a and b local variables of your main() function are unrelated to the a and b members of class LineSegment. You should give LineSegment a constructor by which you can convey the endpoints to it, or at minimum provide a method or methods by which the endpoints can be set after the fact. You must not attempt to compute the segment length before its endpoints are set.

John Bollinger
  • 121,924
  • 8
  • 64
  • 118
0

Neither the member a nor the member b are initialized for pt. You need to initialize them or they are initialized using the default constructor of point which happens to not do any initialization resulting in undefined behavior.

You could e.g. pass the points to the constructor of LineSegment to fix this:

class LineSegment {
public:
    LineSegment(const point& p1, const point& p2)
        : a(p1), b(p2)
    {}
...
};

...

LineSegment pt {a, b};

...

Note: I recommend adding a prefix to member variables. m_ is one option (i.e. you'd use m_a and m_b as member variable names). This way you avoid confusion like this and also avoid shadowing of variables assuming this is the only kind of variable using this prefix.


Edit: You also never call setpoint on b in main; you need to do this before passing the points to the constructor in the above snippet.

fabian
  • 67,623
  • 12
  • 74
  • 102
0

Here is your code, touched up to work:

#include <cmath>
#include <iostream>
// using namespace std;  // CHANGED: Bad practice

class point {
 private:
  float x = 0.0f;  // CHANGED: Add default member initialization
  float y = 0.0f;

 public:
  point() = default;  // CHANGED: Add default constructor
  point(int abscissa, int ordinate) : x(abscissa), y(ordinate) {}  // ADDED
  void setpoint(float abscissa, float ordinate) {
    x = abscissa;
    y = ordinate;
  }
  float getx() const { return x; }  // CHANGED: Mark getters as const

  float gety() const { return y; }
};

class LineSegment {
 public:
  // CHANGED: Add constructor so you can actually build a LineSegment
  LineSegment(point one, point two) : a(one), b(two) {}
  // CHANGED: Made a one-liner
  float length() const {
    return sqrt(pow(a.getx() - b.getx(), 2) + pow(a.gety() - b.gety(), 2));
  }

  // void displayMessage() const { std::cout << result; }  // CHANGED: Not
  // needed

 private:
  // float result;  // CHANGED: Does not need to stored
  point a;
  point b;
};

int main() {
  float q, s;
  std::cout << "Enter two numbers for first point:\n";
  std::cin >> q >> s;
  point a(q, s);  // Can now directly initialize

  float e, r;
  std::cout << "Enter two numbers for second point:\n";
  std::cin >> e >> r;
  point b(e, r);  // CHANGED: Actually put values into b
  // a.getx();  // CHANGED: These do nothing
  // a.gety();
  LineSegment pt(a, b);  // CHANGED: Actually put data into pt
  std::cout << "\nLine Length: " << pt.length() << '\n';  // CHANGED: Make use
                                                          // of functions now
                                                          // available

  return 0;
}

Your biggest issues were not initializing your objects correctly. point b was never given the values e and r, and LineSegment pt was never given any points.

Making those small changes and your code works as expected. Just using a simple example of (0, 0) and (1, 1) provides output of 1.41421, which is root-2, which is correct.

Jarod42
  • 173,454
  • 13
  • 146
  • 250
sweenish
  • 3,215
  • 2
  • 10
  • 19
  • May you explain lines 12 and 29? i don't understand. and why using namespace std; is bad practice? – amir graphici Apr 27 '21 at 20:26
  • For `using namespace std;` https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice?r=SearchResults&s=1|1356.0653 I think you're referring to constructors with your line numbers. Constructors are special class member functions that are responsible for actually building your object. Using them in OOP is foundational. I'd consider changing your learning source/methods if you're in OOP and don't know about constructors yet. – sweenish Apr 27 '21 at 20:30
  • I would suggest making `LineSegment::length` a `const` member function as well. – Nathan Pierson Apr 27 '21 at 22:14