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()
{
    circleType radiusObject(5);
    cylinderType heightObject(3);    
    radiusObject.print();
    heightObject.print();
   
    cout<<"Circle area = " <<radiusObject.getArea()<<endl;
    cout<<"Circle circumference = " <<radiusObject.getCircumference()<<endl;
    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;
}




lazylgAsked:
Who is Participating?
 
jkrCommented:
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
 
bachra04Commented:
In class Circle just declare the class Cylinder friend.
0
 
jkrCommented:
It is not really a good idea to declare derived classes as friends of the base classes - that kinda defeats the purpose ;o)
0
Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
ikeworkCommented:
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
 
ikeworkCommented:
here is a better pi:

double const PI = 3.1415926535897932384626433832795029;

good luck,
ike
0
 
itsmeandnobodyelseCommented:
>>>> 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
 
itsmeandnobodyelseCommented:
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
 
DrAskeCommented:
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
 
DrAskeCommented:
I agree with *itsmeandnobodyelse* :o)
0
 
bhattmayankCommented:
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
 
ikeworkCommented:
bhattmayank, sorry, but i have to shout on you :)

thats no good tip, especially, if you remember cylinderType having a virtual table!!!
 
0
 
itsmeandnobodyelseCommented:
>>>>  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.

All Courses

From novice to tech pro — start learning today.