0

(I'm new to use this platform, sorry if I ask the question incorrectly .)

I'm trying to pass the coordination of point to the segment class, in order to compute length of the segment, but codeblocks return error message: enter image description here could someone tell me how to solve this problem

#include <iostream>
#include <cmath>
using namespace std;
class Point
{
public:
    Point(float in1, float in2):x(in1),y(in2){};
    float x, y;
};

class Segment
{
public:
    Segment(Point in1, Point in2){
        this->a.x = in1.x;
        this->a.y = in1.y;
        this->b.x = in2.x;
        this->b.y = in2.y;
    };
    float length() //return the length of segment
    {
        float delta_x = a.x - b.x, delta_y = a.y - b.y;
        return sqrt( delta_x * delta_x + delta_y * delta_y);
    };
private:
    Point a, b;

};

int main(){
    Point a(12,5),b(6,6);
    Segment seg1(a, b);
    cout << seg1.length();

}
user4581301
  • 33,082
  • 7
  • 33
  • 54
Ainz
  • 5
  • 5
  • Recommendation: Don't use images for error messages. Too many people cannot see images and they are hard to search. Copy and paste the errors into the question as text. – user4581301 Apr 12 '20 at 16:50
  • @user4581301 thanks for recommendation!!! I'll take care for that next time~ – Ainz Apr 12 '20 at 18:54

2 Answers2

2

When you call a constuctor, members are initialized before the body of the constructor is executed. If you do not specify how they should be initialized, they are default constructed, but Point has no default constuctor (= one that can be called without parameters). Not only to fix that, but also in general you should prefer initialization over assignment in the constructor. You can change Segments constructor to:

Segment(Point in1, Point in2) : a(in1.x,in1.y), b(in2.x, in2.y) {}

This is using the initializer list of the constructor and note that the body is empty.

However, I would suggest you to make use of the implicitly declared copy constructor for Point (one that takes a Point as parameter) and write the Segment constructor like this:

Segment(Point in1, Point in2) : a(in1), b(in2) {}
463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
  • Wow! that's detailed and rich explanation! It works! Sorry for long response duration, I was trying to figure out your meaning with my stupid head XD Even though I'm not used to copy constructor, I found my code works as long as I switch my segment's declaration with second version! Does that means I don't have to use copy constructor right? – Ainz Apr 12 '20 at 18:48
  • @FutureWind sorry had to refresh my memory about the rules when the copy constructor is generated by the compiler (always unless you provide your own). Fixed the answer – 463035818_is_not_an_ai Apr 12 '20 at 20:10
  • @idclev463035818 creepy how we are both editing our answers at the same time. – user4581301 Apr 12 '20 at 20:12
  • @FutureWind you dont need to respond to an answer (unless you want to ask for clarification of course). What you should do is accept one of the answers if you think it answers your question. – 463035818_is_not_an_ai Apr 12 '20 at 20:17
  • @user4581301 well yours was more complete from the start, I knew that my "you have to write a copy constructor" was misleading, but only after OP asked for clarification i felt it needed a fix – 463035818_is_not_an_ai Apr 12 '20 at 20:19
1

All class members must be constructed before entering the body of the constructor.

Segment(Point in1, Point in2)
{ // The constructors for a and b WILL be called before this brace
    this->a.x = in1.x;
    this->a.y = in1.y;
    this->b.x = in2.x;
    this->b.y = in2.y;
};

This is easy to do if the members have a default constructor, a constructor that can be called with no arguments. Point has no such constructor. In order to construct a point you must provide in1 and in2 and those can only be provided with a Member Initializer List or by providing Default Member Initializers. The second option is not appropriate here because default values are not desired.

However in this case you can take advantage of Point's automatically-generated copy constructor to make your job a bit easier.

Segment(Point in1, Point in2){
    this->a.x = in1.x;
    this->a.y = in1.y;
    this->b.x = in2.x;
    this->b.y = in2.y;
};

becomes

Segment(Point in1, Point in2):
   a(in1), b(in2) 
{
    //does nothing
};
user4581301
  • 33,082
  • 7
  • 33
  • 54
  • Your answer is elegant and extremely close to my question point! It works! But I don't get where my code goes wrong even though I'm trying to figure out your explanation in first part
    I thought I have to use overloading of "=" to pass the value of Point to Segment, scaring that computer doesn't know what does "=" means while parameter of "=" funtion are class type, but not int, float, and something usual for assignment in c++. Because I'm not used to overloading, I used the constructor's body to assign the Point's value to the Point value under the segment class.
    – Ainz Apr 12 '20 at 18:43