# CALCULATE VOLUME AND TOTAL AREA OF A CYLINDER

Question: Even though x is private, what can I do to make x available in the derived functions cylinderType?

When I compile the cylinderType program I get the following message:

Line          Message
18            'int circleType::x' is private
94            within this context

This message is repeated several time in the following functions:

float cylinderType::getTotalArea()
{
return 2 * x * x  * PI * (x  + y);
}

float cylinderType::getVolume()
{
return PI * x * x + y;
}

cylinderType::cylinderType(int a, int b):circleType(a + b)
{
x = a;
y = b;
}

Entire code:

#include <iostream>

using namespace std;

const float PI = 3.14;

class circleType
{
public:
void print()const;
int getX();
float getArea();
float getCircumference();
circleType();
circleType(int a);

private:
int x;

};

class cylinderType: public circleType
{
public:
void print()const;
int getY();
float getTotalArea();
float getVolume();
cylinderType();
cylinderType(int a, int b = 0);

private:
int y;

};

int main()
{
cylinderType heightObject(3);
heightObject.print();

cout<<"Cylinder total area = "<<heightObject.getTotalArea()<<endl;
cout<<"Cylinder volume = " <<heightObject.getVolume()<<endl;

cin.get();
return 0;
}

int circleType::getX()
{
return x;
}

void circleType::print()const
{
cout<<"r = radius of a circle.  r = "<<x<<", PI = "<<PI<<endl;
cout<<"Formulas for area of circle = (2 * PI * r * r)"<<endl;
cout<<"Formulas for circumferencea of circle = (2 * r * PI)"<<endl;

}

void cylinderType::print()const
{

cout<<"Formula for total area of a cylinder = 2 * r * PI * (r + h)"<<endl;
cout<<"Formula for volume of a cylinder = PI * r * r * h"<<endl;
}

float circleType::getArea()
{
return 2 * PI * x * x;
}

float circleType::getCircumference()
{
return 2 * x * PI;
}

int cylinderType::getY()
{
return y;
}

float cylinderType::getTotalArea()
{
return 2 * x * x  * PI * (x  + y);
}

float cylinderType::getVolume()
{
return PI * x * x + y;
}

circleType::circleType()
{
x = 0;
}

circleType::circleType(int a)
{
x = a;
}

cylinderType::cylinderType(int a, int b):circleType(a + b)
{
x = a;
y = b;
}

###### Who is Participating?

Commented:
Two possibilities:

a) make it a protected member, if applicable

b) Add an accessor member t othe base class, e.g. -- ops, you already have an accessor, so use it:

float cylinderType::getTotalArea()
{
float x = getX();

return 2 * x * x  * PI * (x  + y);
}

float cylinderType::getVolume()
{
float x = getX();

return PI * x * x + y;
}

If you want to be able to change the value also, use

class circleType
{
public:
void print()const;
int getX() const { return x;}
int& getX()  { return x;};

//...
};

Be careful, the above just illustrates the idea, you probably have another 'getX()' somewhere else around, so remove one of these.
0

Commented:
In class Circle just declare the class Cylinder friend.
0

Commented:
It is not really a good idea to declare derived classes as friends of the base classes - that kinda defeats the purpose ;o)
0

Commented:
hi lazylg,

dont forget to add a virtual destructor, at least to the base-class:

class circleType
{
public:
virtual ~circleType()  {}
};

btw: your PI has quite a less precision with only 2 digits!!

hope it helps :)
ike
0

Commented:
here is a better pi:

double const PI = 3.1415926535897932384626433832795029;

good luck,
ike
0

Commented:
>>>> It is not really a good idea to declare derived classes as friends of the base classes - that kinda defeats the purpose

That is true but actually circleType seems not to be a good choice as a baseclass for cylinderType as you could not say "a cylinder *IS A* circle.

I doubt that functions valid for a 'circle' need to make sense for a cylinder as well.

So, I would recommend to change class cylinderType to

class cylinderType
{
public:
void print()const;
int getY();
float getTotalArea();
float getVolume();
cylinderType();
cylinderType(int a, int b = 0);

private:
circleType base;
int y;

};

and make cylinderType a friend of circleType:

class circleType
{
public:
void print()const;
int getX();
float getArea();
float getCircumference();
circleType();
circleType(int a);

friend class cylinderType;

private:
int x;

};

Regards, Alex

0

Commented:
Maybe you could get rid of the 'Type' suffix in the class names ;-)

It makes things easier to talk of Circle and Cylinder rather than circleType and cylinderType.
0

Commented:
Hi  *lazylg* ..

A base class's *public* members are accessible anywhere that the program has a handle(i.e., a name, reference or pointer) to an object of that base class or one of its derived classes.

A base class's *private* members are accessible *only* within the body of that base class and the friends of that base class.

>>a) make it a protected member, if applicable
Using *proteceted* access -as JKR said- offers an intermediate level of protection between *public* and *private* access.

A base classe's *protected* members can be accessed by member and friends of that base class and by members and friends of any classes derived from that base class ...

const double PI = 3.14159;

class circleType
{
public:
void print()const;
int getX();
float getArea();
float getCircumference();
circleType();
circleType(int a);

//private:
protected:
int x;

};

it compiles with - 0 error(s), 0 warning(s)

regards;
0

Commented:
I agree with *itsmeandnobodyelse* :o)
0

Commented:
the other tricky thing ...!
don’t shout on me ...
it’s illegal in c++ code book &#61516;

float cylinderType::getTotalArea()
{
circleType ptrCircleType = (circleType*)(this);
//here we donlt have any virtual method so we can directly cast it to integer and you will get
//  the value of x
int x = (*(int*)(ptrCircleType));      // local x overrides member variable
return 2 * x * x  * PI * (x  + y);
}

Such thing works in one of my program, it will give you weird value if you change class circleType member variables or add any virtual method.

regards
Mayank
0

Commented:
bhattmayank, sorry, but i have to shout on you :)

thats no good tip, especially, if you remember cylinderType having a virtual table!!!

0

Commented:
>>>>  the other tricky thing ...!

That's not tricky but foolish. Both classes were self-made. Why should anyone cast a private member of a class that easily could made protected or could be declared as friend? If you are creating a class with private members, you *know* that you can't access them in derived or non-friend classes. Defining a private member and making some weird pointer casts later is really gaga ...

Regards, Alex
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.