Array inside a class having problems

  • Thread starter Thread starter GregA
  • Start date Start date
  • Tags Tags
    Array Class
Click For Summary
SUMMARY

The discussion centers on the implementation of a class hierarchy in C++ involving geometric shapes, specifically a base class pointType, a derived class circleType, and another derived class cylinderType. The user encountered issues with accessing private members and the misuse of inheritance, leading to compile-time errors. The resolution involved changing the relationship from inheritance to composition, where circleType contains an instance of pointType instead of inheriting from it. This adjustment allowed the program to compile successfully and function as intended.

PREREQUISITES
  • Understanding of C++ class and object-oriented programming concepts
  • Knowledge of inheritance vs. composition in object-oriented design
  • Familiarity with C++ access specifiers (public, private)
  • Basic understanding of geometric calculations (area, circumference, volume)
NEXT STEPS
  • Explore C++ composition vs. inheritance to better understand design patterns
  • Learn about C++ access control and encapsulation best practices
  • Investigate geometric algorithms for calculating surface area and volume
  • Practice debugging C++ code to resolve compile-time and runtime errors effectively
USEFUL FOR

Software developers, particularly those working with C++ and interested in object-oriented programming, as well as students learning about class design and geometric computations.

GregA
Messages
210
Reaction score
0
An exercise I am trying to complete is to create a base class pointType which has functions to get two coordinates, store and print them; then to create another class derived from pointType that will find the radius, centre, area of a circle, and print these; then to create another class cylinderType derived from circleType that will find the volume and surface area of a cylinder as well as printing out all the parameters that make up the cylinder etc...

My program so far is the following:

Code:
#include <iostream>
#include <cmath>

using namespace std;

const double PI = acos(-1);

class pointType //gets information about 2 points x and y
{
public:
	void setCoords(double X, double Y);
	void printCoords() const;
	double getX() const;
	double getY() const;
	pointType();
	pointType(double X, double Y);
private:
	double x;
	double y;
};

class circleType: public pointType //gets information about a circle with radius rad, centered at point (x,y)
					//derived from pointType
{
public:
	void setCircle(double X, double Y, double rad);
	void setCentre();
	double calcArea() const;
	void setArea();
	void printCircleDetails() const;
	circleType();
	circleType(double X, double Y, double rad);
private:
	double centre[2];
	double radius;
	double area;
};

int main()
{
circleType myCircle1(5,6,7);
cout << myCircle1.centre[0] << endl;
myCircle1.printCircleDetails();

cout << "\n\n";
circleType myCircle2;
myCircle2.setCircle(5,6,7);
myCircle2.printCircleDetails();
return 0;
}

void pointType::setCoords(double X, double Y)
{
	x = X;
	y = Y;
}
void pointType::printCoords() const
{
	cout << "coordinates of point are: (" << x << "," << y << ")" << endl;
}

double pointType::getX() const
{
	return x;
}

double pointType::getY() const
{
	return y;
}

pointType::pointType()
{
	x = 0;
	y = 0;
}

pointType::pointType(double X, double Y)
{
	x = X;
	y = Y;
}

void circleType::setCircle(double X, double Y, double rad)
{
	pointType::setCoords(X,Y);
	if(rad < 0.0)
		radius = -1*rad;
	else
		radius = rad;
}

void circleType::setCentre()
{
	centre[0] = pointType::getX();
	centre[1] = pointType::getY();
}

double circleType::calcArea() const
{
	return PI*pow(radius,2);
}

void circleType::setArea()
{
	area = calcArea();
}

void circleType::printCircleDetails()const
{
	cout << "centre = (" << centre[0] << "," << centre[1] << ")"
		<< ", radius = " << radius << ", area = " << calcArea();
}

circleType::circleType():pointType()
{
	radius = 0;
	centre[0] = 0;
	centre[1] = 0;
}

circleType::circleType(double X, double Y, double rad):pointType(X,Y)
{
	radius = rad;
	centre[0] = pointType::getX();
	centre[1] = pointType::getY();
}

The problem I'm having so far is that in circleType I want to store the info about the circle's centre in an array with just 2 elements but at compile time I get the following:

cylinderType.cpp: In function ‘int main()’:
cylinderType.cpp:34: error: ‘double circleType::centre [2]’ is private
cylinderType.cpp:42: error: within this context

Furthermore if I comment out the keyword private (which I don't want to do) then though the constructor with parameters seems to work, the function setCentre isn't.

I have played around with test programs that have arrays as private members and had no problems but with this, it doesn't like it and I don't know what the problem is (though I bet its something stupid on my part)

Can someone point out what I'm doing wrong?
 
Technology news on Phys.org
First, you are using inheritance wrong. Inheretance represents an "is a" relationship, but a circle is not a point so it doesn't make sense for circles to inherit from points.

What you are looking for is composition which expresses the "has a" relationship. A circle has a center (which is a point), and a cylinder has two circles. This is expressed by making a circle class which has a point as a data member.
 
In your main function you've written

Code:
cout << myCircle1.centre[0] << endl;

What's the purpose behind this code?

(For what it's worth, commenting out this line gets your code to compile and -- at least for the data points specified in the code -- gives you a correct answer for the area of the circle.)
 
DaleSpam said:
First, you are using inheritance wrong. Inheretance represents an "is a" relationship, but a circle is not a point so it doesn't make sense for circles to inherit from points.

What you are looking for is composition which expresses the "has a" relationship. A circle has a center (which is a point), and a cylinder has two circles. This is expressed by making a circle class which has a point as a data member.

good point! :smile:

For what its worth I've redone my class circleType following your advice and things seem to be working ok...though I'm still niggled as to why my compiler threw an error at me defining a private array!
Code:
#include <iostream>
#include <cmath>

using namespace std;

const double PI = acos(-1);

class pointType
{
public:
	void setCoords(double X, double Y);
	void printCoords() const;
	double getX() const;
	double getY() const;
	pointType();
	pointType(double X, double Y);
private:
	double x;
	double y;
};

class circleType
{
public:
	void setCircle(double X, double Y, double rad);
	void setRadius();
	double calcArea() const;
	void setArea();
	void printCircleDetails() const;
	circleType();
	circleType(double X, double Y, double rad);
private:
	pointType centre;
	double radius;
	double area;
};

int main()
{
circleType myCircle1;
myCircle1.setCircle(2.0,3.0,4);
myCircle1.printCircleDetails();

return 0;
}

void pointType::setCoords(double X, double Y)
{
	x = X;
	y = Y;
}
void pointType::printCoords() const
{
	cout << "coordinates of point are: (" << x << "," << y << ")" << endl;
}

double pointType::getX() const
{
	return x;
}

double pointType::getY() const
{
	return y;
}

pointType::pointType()
{
	x = 0;
	y = 0;
}

pointType::pointType(double X, double Y)
{
	x = X;
	y = Y;
}

void circleType::setCircle(double X, double Y, double rad)
{
	centre.setCoords(X,Y);
	if(rad < 0.0)
		radius = -1*rad;
	else
		radius = rad;
}

double circleType::calcArea() const
{
	return PI*pow(radius,2);
}

void circleType::setArea()
{
	area = calcArea();
}

void circleType::printCircleDetails()const
{
	cout << "centre = (" << centre.getX() << "," << centre.getY() << ")"
		<< ", radius = " << radius << ", area = " << calcArea();
}

circleType::circleType()
{
	radius = 0;
	centre.setCoords(0,0);
}

circleType::circleType(double X, double Y, double rad):centre(X,Y)
{
	radius = rad;
}
 
Last edited:
shoehorn said:
In your main function you've written

Code:
cout << myCircle1.centre[0] << endl;

What's the purpose behind this code?

(For what it's worth, commenting out this line gets your code to compile and -- at least for the data points specified in the code -- gives you a correct answer for the area of the circle.)

Thanks for the reply. the purpose behind that code was to try and debug...it is a relic I would have deleted if the program worked...Though commenting out that line gets it to compile it doesn't seem to be putting the correct values into centre[0] and centre[1]...it has them both set to 0
 
GregA said:
...though I'm still niggled as to why my compiler threw an error at me defining a private array!

It didn't. What it flagged was the fact that you were trying to access a private data member (the array centre[]) from outside the class. At least, that's what you seemed to be doing.
 
shoehorn said:
It didn't. What it flagged was the fact that you were trying to access a private data member (the array centre[]) from outside the class. At least, that's what you seemed to be doing.

Hmm...I cannot copy the line numbers from my text file (using gedit for linux) but it throws that error on the following line (in red)

private:
double centre[2];

Though I can now see the problem with that line you posted :smile:
 
arrggghhh! :cry:

I've written up the exercise including cylinderType but I'm having major problems assigning a value to surfaceArea and volume...I know exactly where things are going wrong but for the life in me can't see why there is a problem.
running calcSurfArea and calcVolume work fine...setting surfaceArea = calcSurfArea() (or anything else!) doesn't work, ditto for volume. :frown:

My program is here, I have marked the areas where I have commented things out with //debugging:
PHP:
#include <iostream>
#include <cmath>

using namespace std;

const double PI = acos(-1);

class pointType
{
public:
	void setCoords(double X, double Y);
	void printCoords() const;
	double getX() const;
	double getY() const;
	pointType();
	pointType(double X, double Y);
private:
	double x;
	double y;
};

class circleType
{
public:
	void setCircle(double X, double Y, double rad);
	void setRadius();
	double calcArea() const;
	void setArea();
	double calcCircumfrence() const;
	void setCircumfrence();
	void printCircleDetails() const;
	circleType();
	circleType(double X, double Y, double rad);
private:
	pointType centre;
	double radius;
	double area;
	double circumfrence;
};

class cylinderType
{
public:
	void setCylinder(double X, double Y, double H, double rad);
	double calcSurfArea() const;
	void printHeight();
	void setSurfArea();
	double calcVolume() const;
	void setVolume();
	void printCylinderDetails() const;
	cylinderType();
	cylinderType(double X, double Y, double H, double rad);
//private: //debugging
	circleType cap;
	double height;
	double surfaceArea;
	double volume;
};

int main()
{

/*circleType myCircle1;
myCircle1.setCircle(1,2,3);
myCircle1.printCircleDetails();
count << endl;*/

cylinderType myCylinder1;
myCylinder1.setCylinder(1,2,3,4);
myCylinder1.printCylinderDetails();

count << endl << myCylinder1.calcSurfArea(); //debugging
count << endl << myCylinder1.surfaceArea; //debugging
count << endl << myCylinder1.calcVolume(); //debugging
count << endl << myCylinder1.volume; //debugging
return 0;
}

void pointType::setCoords(double X, double Y)
{
	x = X;
	y = Y;
}
void pointType::printCoords() const
{
	count << "coordinates of point are: (" << x << "," << y << ")" << endl;
}

double pointType::getX() const
{
	return x;
}

double pointType::getY() const
{
	return y;
}

pointType::pointType()
{
	x = 0;
	y = 0;
}

pointType::pointType(double X, double Y)
{
	x = X;
	y = Y;
}

void circleType::setCircle(double X, double Y, double rad)
{
	centre.setCoords(X,Y);
	if(rad < 0.0)
		radius = -1*rad;
	else
		radius = rad;
}

double circleType::calcArea() const
{
	return PI*pow(radius,2);
}

void circleType::setArea()
{
	area = calcArea();
}

double circleType::calcCircumfrence() const
{
	return 2*PI*radius;
}

void circleType::setCircumfrence()
{
	circumfrence = calcCircumfrence();
}

void circleType::printCircleDetails()const
{
	count << "centre = (" << centre.getX() << "," << centre.getY() << ")"
		<< ", radius = " << radius << ", area = " << calcArea();
}

circleType::circleType()
{
	radius = 0;
	centre.setCoords(0,0);
	area = 0;
}

circleType::circleType(double X, double Y, double rad):centre(X,Y)
{
	radius = rad;
	area = calcArea();
}

void cylinderType::setCylinder(double X, double Y, double H, double rad)
{
	cap.setCircle(X,Y,rad);
	height = H;
}

double cylinderType::calcSurfArea() const
{
	return 2*(cap.calcArea()) + height*cap.calcCircumfrence();
}

void cylinderType::setSurfArea()
{
	surfaceArea = 5; // calcSurfArea(); //debugging
}

double cylinderType::calcVolume() const
{
	return height*cap.calcArea();
}

void cylinderType::setVolume()
{
	volume = 5; //calcVolume(); //debugging
}

void cylinderType::printCylinderDetails() const
{
	count << "cap details: ";
	cap.printCircleDetails();
	count << "\nother details: surface area = " << surfaceArea << ", volume = " << volume;
}

cylinderType::cylinderType()
{
	height = 0;
	cap.setCircle(0,0,0);
	surfaceArea = 0;
	volume = 0;
}

cylinderType::cylinderType(double X, double Y, double H, double rad):cap(X,Y,rad)
{
	height = 0;
	surfaceArea = calcSurfArea();
	volume = calcVolume();
}

can anyone tell me why I cannot assign values to surfaceArea or volume?
 
So your problem is that myCylinder1.surfaceArea is never set to the proper value? You have to decide in which function you want that to happen. If you want calcSurfArea to also set the value, then it can't be a const function. If you want setSurfArea to set the value, then you have to call it somewhere.
 
  • #10
JaWiB said:
So your problem is that myCylinder1.surfaceArea is never set to the proper value? You have to decide in which function you want that to happen. If you want calcSurfArea to also set the value, then it can't be a const function. If you want setSurfArea to set the value, then you have to call it somewhere.

Thanks for the reply...I was just about to edit the above post to say I'd figured out what was going on...no function actually makes use of setSurfArea() or setVolume() :redface: I'm a fool!:smile:

Now that I know why I'm having that problem...I can actually do away with those two functions now (I won't be building anymore classes that need them)...cheers everyone :smile:
 
Last edited:

Similar threads

  • · Replies 23 ·
Replies
23
Views
2K
  • · Replies 13 ·
Replies
13
Views
2K
  • · Replies 23 ·
Replies
23
Views
3K
  • · Replies 5 ·
Replies
5
Views
3K
  • · Replies 4 ·
Replies
4
Views
2K
  • · Replies 1 ·
Replies
1
Views
3K
  • · Replies 6 ·
Replies
6
Views
2K
Replies
2
Views
2K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 89 ·
3
Replies
89
Views
6K