Solved

CALCULATE VOLUME AND TOTAL AREA OF A CYLINDER

Posted on 2006-03-23
Medium Priority
808 Views
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;
}

0
Question by:lazylg
• 3
• 3
• 2
• +3

LVL 86

Accepted Solution

jkr earned 672 total points
ID: 16276956
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

LVL 2

Expert Comment

ID: 16276957
In class Circle just declare the class Cylinder friend.
0

LVL 86

Expert Comment

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

LVL 20

Assisted Solution

ikework earned 664 total points
ID: 16278711
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

LVL 20

Expert Comment

ID: 16278753
here is a better pi:

double const PI = 3.1415926535897932384626433832795029;

good luck,
ike
0

LVL 39

Assisted Solution

itsmeandnobodyelse earned 664 total points
ID: 16279297
>>>> 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

LVL 39

Expert Comment

ID: 16279311
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

LVL 9

Expert Comment

ID: 16279313
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

LVL 9

Expert Comment

ID: 16279327
I agree with *itsmeandnobodyelse* :o)
0

Expert Comment

ID: 16283130
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

LVL 20

Expert Comment

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

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

0

LVL 39

Expert Comment

ID: 16284769
>>>>  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

Featured Post

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A Bare Metal Image backup allows for the restore of an entire system to a similar or dissimilar hardware. They are highly useful for migrations and disaster recovery. Bare Metal Image backups support Full and Incremental backups. Differential backupâ€¦
The Delta outage: 650 cancelled flights, more than 1200 delayed flights, thousands of frustrated customers, tens of millions of dollars in damages â€“ plus untold reputational damage to one of the worldâ€™s most trusted airlines. All due to a catastrophâ€¦
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor anâ€¦
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
Suggested Courses
Course of the Month16 days, 23 hours left to enroll