simple "class" question

I am new to both c and c++. A few weeks ago I started learning c++ using MIT's online courseware (class number 6.096). Everything was going great until I hit classes. Now I am really struggling (bad part about MIT's free course material, no TA's nor instructors to help).

Today I decided I was just going to program some classes myself and it was going great until I hit a brick wall. In my code below I defined a class called "Point". Then I tried to define a "Line" class that consists of two Points. The error section is outlined in comments below.

My guess is that the problem is very obvious to an experienced c++ programmer. My hope is I will understand the explanation.

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
#include <iostream>
#include <math.h>

using namespace std;

class Point {
private: double x,y;
public:
    Point (){};
    Point(double x=0,double y=0){
        this->x = x;
        this->y = y;
    }
    double GetX(){return x;};
    double GetY(){return y;};
    void SetX(double x) {this->x = x;};
    void SetY(double y) {this->y = y;};
    void SetXY(double x, double y) {SetX(x); SetY(y);};
    void PrintVal(){std::cout << "("<<x<<","<<y<<")";};
    void PrintVal(char* prefix) {std::cout << prefix << "=";PrintVal();std::cout << "\n";};
    Point(Point &o){
        x = o.x;
        y = o.y;};
};

class Line {
public:
    Point p1(),p2();
    Line(Point *p1,Point *p2){};
    double GetLength(){
        double x,y;
// THE ERROR IS HERE vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
        x = (p1.GetX() - p2.GetX());  // COMPILE ERROR.
        x = x*x; //square it
        y = (p1.GetY() - p2.GetY());  // COMPILE ERROR.
        y = y*y;
// THE ERROR IS HERE ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        return sqrt(x+y); };
};

int main(){
    Point p1(3.8,4.22);
    Point p2(p1);
    p2.SetXY(1.66,9.221);
    p1.PrintVal("p1");
    p2.PrintVal("p2");
    return 0;
};
In the class Point , the second constructor is considered as the default constructor because it does not necessary required any arguments because of the default parameters .

For the other errors , you tried to call the constructor in the class declaration not within a method member scope which is illegal except for static member that are const.

Here is some modification :

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
#include <iostream>
#include <math.h>

using namespace std;

class Point {
private: 
	double x,y;
public:
 
    Point(double x=0,double y=0)
	{
        this->x = x;
        this->y = y;
    }
    double GetX(void) const
	{
		return x;
	}
    double GetY(void) const
	{
		return y;
	}
    void SetX(double x) 
	{
		this->x = x;
	}
    void SetY(double y) 
	{
		this->y = y;
	}
    void SetXY(double x, double y) 
	{
		SetX(x); SetY(y);
	}
    void PrintVal(void) const
	{
		std::cout << "("<<x<<","<<y<<")";
	}
    void PrintVal(char* prefix)  const
	{
		std::cout << prefix << "=";PrintVal();std::cout << "\n";
	}
    Point(Point &o)
	{
        x = o.x;
        y = o.y;
	}
};

class Line {
public:
    Point p1;
	Point p2;

	Line(void)
		: p1()
		, p2()
	{
	}
    Line(Point *p1,Point *p2)
		: p1(*p1)
		, p2(*p2)
	{
	}
    double GetLength(void) const
	{
        double x,y;

        x = (p1.GetX() - p2.GetX());  
        x *= x; //square it
        y = (p1.GetY() - p2.GetY());  
        y *= y;

        return sqrt(x+y); 
	}
};

int main(int argc , char* argv[])
{
    Point p1(3.8,4.22);
    Point p2(p1);
    p2.SetXY(1.66,9.221);
    p1.PrintVal("p1");
    p2.PrintVal("p2");

	system("pause");

    return EXIT_SUCCESS;
}
Thank you for your very thorough explanation. I am studying your code and explanation and going back to the lecture notes again.

In the class Point , the second constructor is considered as the default constructor because it does not necessary required any arguments because of the default parameters .


Yes, sadly I knew this. I threw this line in after hours of fighting the error, blindly hoping it might appease the compiler. This is when I know I am unlearning and have reached the point where I need to ask for help.

For the other errors , you tried to call the constructor in the class declaration not within a method member scope which is illegal except for static member that are const.


This part I need to go back and study more. Thank you again for pointing me in the right direction so I can get back on track.

you're welcome.
OK, I re-read the section on "const member functions".

Is it safe to assume that every time a class method returns a variable value that it should be a const and when a method modifies variable values it should not be const?

*EDITS*
OK, I thought I was starting to understand this, but not there yet. In the "Additional Material" notes it says:
"To declare a const member function, place the const keyword after the closing parenthesis of the argument list. The const keyword is required in both the prototype and the definition."

In the lecture notes they are not always consistent with this. Here is a code snippit:

1
2
3
4
5
6
7
class Car: public Vehicle {
    string style;
public:
    Car(const string &myLicense, const int myYear, const string &myStyle)
        :Vehicle(myLicense, myYear), style(myStyle){}
    const string &getStyle() {return style;}
};


So why does the last line not:
"const string &getStyle() const {return style;}"
Last edited on
So why does the last line not:
1
2
const string & getStyle() const 
{return style; }" 


It should be.

The two const keywords convey two different things.

The first says that the reference to the string that is being returned may not be changed.

The second tells the compiler that the function does not modify the class.


OK, thank you, I will correct the lecture notes. I wish the lecture notes were more consistent, this can be confusing enough (for newbies).
Just to add to AA's answer - that getStyle() very well could - and probably should - be defined as a const function, i.e.

const string &getStyle() const {return style;}.

The method doesn't modify the state of the object, and the reference it returns is const, so it can't be used to modify the state of the object either. So it would have been better to make the method const, in exactly the way you suggested.

Making methods const-correct is one of those things people often forget to do, even experienced professional developers. Usually, it's only when you (or someone else) first tries to use a const object of that type that you suddenly realise that you've forgotten to make some of your methods const - e.g.

1
2
3
const Car myPorche("1234567", 2001, "Sports car");
std::cout << "My car is a " << myPorche.getStyle();  // COMPILE ERROR - because we didn't
                                                     // make getStyle() a const method. 


Last edited on
MikeyBoy, this has been clearly explained by everybody, but it took your explanation to really make it all clear to me. Maybe it just took repetition.

Let's make sure I got this concept...

Basically by making the method itself and the code "const" you are insuring that if somebody assigns the class to a constant rather than to a variable it won't throw a compiler error.

If the only thing the method is doing is returning a value (versus changing it), there is absolutely no downside to making it const.

I assume some professional programmers don't catch their mistake because they only assign the class to a variable when debugging. Therefore I should get in the habit now of always making "Get" methods const.

I hope this is right because a light bulb finally came on.
Topic archived. No new replies allowed.