i am tring to code in c and am new. So,is there a way to define a derived class in the base class by predefining the base class before the base class
class rect:public area{
void rect();
};
class area
{
public:
int a,rl,rb,tb,th;
void getdata()
{
cout<<"1.Calculate rectangle: ";
cout<<"2.Calculate triangle: ";
cout<<"Enter your choice: ";
cin>>a;
switch (a)
{
case 1:
cout<<"Enter length";
cin>>rl;
cout<<"Enter breadth";
cin>>rb;
rect r;
break;
The code in derived class is
class rect:public area
{
public:
rect(){
cout<<"The area of rectangle is:"<<rl*rb;
}
};
But i can't seem to be able to predefine a base class is it the limitation in c or is there some problem in the code.
CodePudding user response:
Inheritance should be used for "is a" relationships, composition for "has a" relationships. Can you say that a rectangle "is an" area? No, a rectangle "has an" area. So the correct way would be to have a class rect
that has a member variable or function that contains or returns the area of the rectangle.
You can however say that a rectangle "is a" shape, and every shape has an area. So then you would create a class shape
first, and define a virtual
function for getting its area:
class shape {
public:
virtual float get_area() const = 0;
...
};
And then derive class rect
from shape
like so:
class rect: public shape {
public:
float get_area() const override {
return length * breadth;
}
...
};
As for get_data()
, this should probably be a free-standing function, not a member of any class.
CodePudding user response:
Example for non-circalar inheritance :
#include <cmath>
#include <iostream>
//-------------------------------------------------------------------------------------------------
// define constant for pi (I don't want to include the "C" style macro)
// if you have C 20 you can also use std::numbers::pi_v<double>
namespace constants
{
const double pi = std::acos(-1.0);
}
//-------------------------------------------------------------------------------------------------
// define an interface (abstract baseclass) for things
// where you can calculate an area of.
class area_itf
{
public:
virtual ~area_itf() = default;
virtual double area() const = 0;
protected:
area_itf() = default;
};
//-------------------------------------------------------------------------------------------------
// rectangle class
class rectangle_t :
public area_itf
{
public:
rectangle_t(const double width, const double height) :
m_width{ width },
m_height{ height }
{
}
double area() const override
{
return m_width * m_height;
}
private:
double m_width;
double m_height;
};
//-------------------------------------------------------------------------------------------------
// circle class
class circle_t :
public area_itf
{
public:
explicit circle_t(const double radius) :
m_radius{ radius }
{
}
double area() const override
{
return 2.0 * constants::pi * m_radius * m_radius;
}
private:
double m_radius;
};
//-------------------------------------------------------------------------------------------------
// function to show area
// now it doesnt matter if we pass a circle or a rectangle
// they both implment the same interface and can be accepted
// by this function.
void show_area(const char* name, const area_itf& object)
{
std::cout << " area of " << name << " = " << object.area() << "\n";
}
int main()
{
rectangle_t rectangle{ 2.0, 3.0 };
circle_t circle{ 2.0 };
show_area("rectangle", rectangle);
show_area("circle", circle);
return 0;
}