Hey guys, so I just started learning computational geometry, and I decided to make a class for a Point and a class for a Ray. This is my code:

#include <iostream>
#include <string>

using namespace std;

class Point {
  public:
    double x, y;

    Point(double x, double y) {
      this->x = x;
      this->y = y;
    }
};

class Ray {
  public:
    Point start, end;

    Ray(Point start, Point end) {
      this->start = start;
      this->end = end;
    }
};

int main() {
  cout << "If only this worked..." << endl;
}

Now, when I comment out the Ray class, the Point class works fine. However, when I make the Ray class, it wont compile. This is what I get:

"C:\Users\Matt\Desktop\C++\geom.cpp||In constructor 'Ray::Ray(Point, Point)':|
C:\Users\Matt\Desktop\C++\geom.cpp|20|error: no matching function for call to 'Point::Point()'|
C:\Users\Matt\Desktop\C++\geom.cpp|10|note: candidates are: Point::Point(double, double)|
C:\Users\Matt\Desktop\C++\geom.cpp|6|note: Point::Point(const Point&)|
C:\Users\Matt\Desktop\C++\geom.cpp|20|error: no matching function for call to 'Point::Point()'|
C:\Users\Matt\Desktop\C++\geom.cpp|10|note: candidates are: Point::Point(double, double)|
C:\Users\Matt\Desktop\C++\geom.cpp|6|note: Point::Point(const Point&)|
||=== Build finished: 6 errors, 0 warnings ===|
"

Can anybody help me get something that at least compiles and be so kind to explain what I did wrong? Thanks!

The problem is in these lines:

Point start, end;

Point(double x, double y) {
      this->x = x;
      this->y = y;
}

Your Point class has one constructor, that takes two arguments. However, no where in the Ray class you tell it what the arguments should be. So the compiler is assuming that you want to call Point's default constructor. This default constructor has no arguments and only gets generated when you don't implement any other constructor.

So in this case you did implement another constructor, so the default constructor is not created.

What you want to do is specify how to create the start and end Points, since you want to copy them from the values passed in the Ray's constructor, you need to write:

Ray(Point start, Point end) :
    this->start( start ),
    this->end  ( end ) 
{
   // constructor execution
}

What this will do is call the implicitly generated copy constructor of the Point class.

This syntax is called an initialization list. The reason this special syntax is needed, is that when the constructor starts to execute, the object already needs to be created. So it needs to know how to create all of the member variables.

Another note: You should probably rename Point start, end; in the Ray class, then you don't need to use this->start in the Ray's constructor.
It is 'customary' to prepend private member variable with m_ or append them with _ (so m_start or start).

Edited 5 Years Ago by thelamb: n/a

You should provide default initialization for the Point class as so :

class Point{
 double x_,y_;
public:
 Point( double x  = 0.0 , double y = 0.0) 
  : x_(x) , y_(y) //use initialization list to initialize variables
  {}
};

the problem with your code what that there was no default constructor that take nothing as parameter.

This article has been dead for over six months. Start a new discussion instead.