~Don't use a "get" function to set data~
This is a long post, but that's what happens when all I have to do is enjoy my coffee :)
Private variables/functions (members) and constructors/destructors make your class much safer/easier to use.
Lets make a Rectangle class:
1 2 3 4 5 6 7 8 9
|
class Rectangle{
public:
double width;
double height;
double area;
Rectangle(void)
{ /* Nothing */ }
};
|
We have issues right away:
1 2 3
|
// main
Rectangle myRect;
cout << area;
|
Area (and width and height) is garbage so our cout is worthless. We can fix this in main
1 2 3 4 5
|
Rectangle myRect;
myRect.width = 0;
myRect.height = 0;
myRect.area = myRect.width * myRect.height;
cout << area;
|
But now we have to remember to do this
every time we declare a Rectangle. A constructor will fix this. We can also overload the constructor, and make things a little quicker:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
class Rectangle{
public:
double width;
double height;
double area;
Rectangle(void)
{
width = 0;
height = 0;
area = width * height;
}
Rectangle(double w, double h)
{
width = w;
height = h;
area = width * height;
}
};
|
Now this will make sense:
1 2 3 4 5
|
Rectangle myRect;
cout << myRect.area;
Rectangle anotherRect(4,5);
cout << anotherRect.area;
|
We still have a big problem with the fact that these are public variables:
1 2 3
|
Rectangle myRect(4,5);
myRect.area = 6;
cout << myRect.area;
|
So we make area private:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
class Rectangle{
private:
double area;
public:
double width;
double height;
Rectangle(void)
{ /* Same as before */ }
Rectangle(double w, double h)
{ /* Same as before */}
// Now we need this:
double getArea(void) { return area; }
};
|
We are still in trouble though (even more actually), because we can do this:
1 2 3 4
|
Rectangle myRect(4,5);
cout << myRect.getArea();
myRect.width = 10;
cout << myRect.getArea();
|
We don't want to be able to change the width or height without updating the area, so we make them private too:
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
|
class Rectangle{
private:
double area;
double width;
double height;
public:
Rectangle(void)
{ /* Same as before */ }
Rectangle(double w, double h)
{ /* Same as before */}
// Accessors
double getArea(void) { return area; }
double getWidth(void) { return width; }
double getHeight(void) {return height; }
// Mutators
void setWidth(double w)
{
width = w;
area = width * height;
}
void setHeight(double h)
{
height = h;
area = width * height;
}
};
|
Now there is no way that area is not the actual area of the rectangle. In fact, we don't need an "area" member at all.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
class Rectangle{
private:
double width;
double height;
public:
Rectangle(void)
: width(0), height(0) // This is a better way than within the braces
{}
Rectangle(double w, double h)
: width(w), height(h)
{}
// Accessors
double getArea(void) { return width * height; }
double getWidth(void) { return width; }
double getHeight(void) {return height; }
// Mutators
void setWidth(double w) { width = w; }
void setHeight(double h) { height = h; }
};
|
Now we can do this:
1 2 3 4 5 6 7 8 9 10 11 12 13
|
int main(void)
Rectangle myRect;
for (int i = 0; i < 10; i++)
{
myRect.setWdith(i);
for (int j = 0; j < 10; j++)
{
myRect.setHeight(j);
cout << myRect.getWidth() << " * " << myRect.getHeight() << " = " myRect.getArea() << endl;
}
}
return 0;
}
|