Polymorphism vs Inheritance. Diffrence? - c++

I dont understand the diffrence between Polymorphism and Inheritance... They Litterarly do the same thing...
Simple Example Of Polymorphism:
class shape {
public:
void setValues(int height_, int width_) {
height = height_, width = width_;
}
protected:
int height, width;
private:
};
class rectangle :public shape, public ThreeDView{
public:
int area() {
return(shape::height*shape::width);
}
float threeDArea() {
return(((shape::height*shape::width)/2)*(std::cos(Z_LENGTH)));
}
};
class ThreeDView{
public:
void setZLength(int value) {
Z_LENGTH = value;
}
int setCompact(bool ans) {
compact = ans;
}
float getZLength() {
return Z_LENGTH;
}
bool getCOMPACT() {
return compact;
}
protected:
float Z_LENGTH;
bool compact;
private:
unsigned char ZCHAR = 'Z';
};
class triangle :public shape {
public:
int area() {
return((shape::height * shape::width) / 2);
}
};
int main(){
rectangle rect2;
triangle trng2;
shape *poly = &rect2;
shape *poly2 = &trng2;
poly->setValues(2,3);
poly2->setValues(5,4);
std::cout << "AREA : " << trng1.area() << "AREA RECT : \n" <<rect1.area() << std::endl;
}
Above example translated to Inheritance:
class shape {
public:
void setValues(int height_, int width_) {
height = height_, width = width_;
}
protected:
int height, width;
private:
};
class rectangle :public shape, public ThreeDView{
public:
int area() {
return(shape::height*shape::width);
}
float threeDArea() {
return(((shape::height*shape::width)/2)*(std::cos(Z_LENGTH)));
}
};
class triangle :public shape {
public:
int area() {
return((shape::height * shape::width) / 2);
}
};
int main(){
rectangle rect2;
triangle trng2;
rect2.setValues(2,3);
trng2.setValues(5,4);
std::cout << "AREA : " << trng1.area() << "AREA RECT : \n" <<rect1.area() << std::endl;
}
Please tell me diffrence. Honestly i dont even see the use of Polymorphism! Thanks for helping!

Here's a version of your first example, that actually uses polymorphism:
#include <iostream>
#include <string>
class shape
{
public:
void setValues(int height_, int width_)
{
height = height_;
width = width_;
}
virtual int area() = 0; // This is needed for polymorphism to work
virtual std::string name() = 0;
protected:
int height;
int width;
};
class rectangle : public shape
{
public:
int area()
{
return height * width;
}
std::string name()
{
return "Rectangle";
}
};
class triangle :public shape
{
public:
int area()
{
return height * width / 2;
}
std::string name()
{
return "Triangle";
}
};
void print_area(shape& poly)
{
std::cout << poly.name() << ' ' << poly.area() << '\n';
}
int main()
{
rectangle rect;
triangle trng;
rect.setValues(2, 3);
trng.setValues(5, 4);
print_area(rect);
print_area(trng);
}
The first big change is that I declare the virtual function area in the shape class. For polymorphism to work, the functions must be declared in the base class as virtual. The "assignment" to 0 is simply telling the compiler that it's an abstract function, and the child-classes must override that function.
The second big change is that I use a function to print the area, one that only takes a reference to the base shape class. You must use references or pointers to the base class for polymrphism to work, not use the actual objects directly like in your example.
This works as expected.

Related

How to ask the user to input the number in my code in order to print out the result

How can I ask the user to input those two numbers and print out the result in C++ here? Please, I need your help. I am new to C++.
#include <iostream>
using namespace std;
class Polygon {
protected:
int width, height;
public:
void set_values (int a, int b)
{ width=a; height=b; }
virtual int area ()
{ return 0; }
};
class Rectangle: public Polygon {
public:
int area ()
{ return width * height; }
};
class Triangle: public Polygon {
public:
int area ()
{ return (width * height / 2); }
};
int main () {
Rectangle rect;
Triangle trgl;
Polygon * ppoly1 = &rect;
Polygon * ppoly2 = &trgl;
ppoly1->set_values (4,5);
ppoly2->set_values (4,5);
cout << ppoly1->area() << '\n';
cout << ppoly2->area() << '\n';
return 0;
}
I would suggest you to read about constructors a little bit, you can use cin and cout here. Please find this code and see how I have done for rectangle.
#include <iostream>
using namespace std;
class Polygon {
protected:
int width, height;
public:
void set_values (int a, int b)
{ width=a; height=b; }
virtual int area ()
{ return 0; }
};
class Rectangle: public Polygon {
private:
int a, b;
public:
Rectangle(){
cout<<"Please enter height and width: ";
cin>>a>>b;
set_values(a,b);
}
int area ()
{ return width * height; }
};
class Triangle: public Polygon {
public:
int area ()
{ return (width * height / 2); }
};
int main () {
Rectangle rect;
Triangle trgl;
Polygon * ppoly1 = &rect;
Polygon * ppoly2 = &trgl;
//ppoly1->set_values (4,5);
ppoly2->set_values (4,5);
cout << ppoly1->area() << '\n';
cout << ppoly2->area() << '\n';
return 0;
}

Derived classes' attributes are empty

I am new to C++ and I am currently playing with inheritance. I am creating a base Polygon class that is inherited by Rectangle and Triangle classes respectively. From there I want to print out the area as defined in calcArea. However, the output of my derived class instances seem to be null.
From what I understand the Polygon:(name, width, height) can help to initialize variables that already exist in the base class. Thanks for all the help!
Here's my code:
#include <iostream>
#include <string>
using namespace std;
enum Polytype {POLY_PLAIN, POLY_RECT, POLY_TRIANG};
class Polygon
{
public:
Polygon(string name, double width, double height){
_name = name;
_width = width;
_height = height;
_polytype = POLY_PLAIN;
}
virtual ~Polygon()
{
cout << "Destroying polygon" << endl;
}
virtual Polytype getPolytype(){
return _polytype;
}
virtual void setPolytype(Polytype polytype){
_polytype = polytype;
}
virtual string getName(){
return _name;
}
virtual double calcArea(){
return _width * _height;
}
private:
string _name;
double _width;
double _height;
Polytype _polytype;
};
class Rectangle: public Polygon
{
public:
Rectangle(string name, double width, double height) : Polygon(name, width, height){
_polytype = POLY_RECT;
};
~Rectangle()
{
cout << "Destroying rectangle" << endl;
}
Polytype getPolytype(){
return _polytype;
}
void setPolytype(Polytype polytype){
_polytype = polytype;
}
double calcArea(){
return _width * _height;
}
string getName(){
return _name;
}
private:
string _name;
double _width;
double _height;
Polytype _polytype = POLY_RECT;
};
class Triangle: public Polygon
{
public:
Triangle(string name, double width, double height) : Polygon(name, width, height){
_polytype = POLY_TRIANG;
};
~Triangle()
{
cout << "Destroying triangle" << endl;
}
Polytype getPolytype(){
return _polytype;
}
void setPolytype(Polytype polytype){
_polytype = polytype;
}
string getName(){
return _name;
}
double calcArea(){
return 0.5 * _width * _height;
}
private:
string _name;
double _width;
double _height;
Polytype _polytype;
};
int main(){
//Initialize rectangle and triangle and store them onto the stack
Rectangle rect("RectA", 10.0, 20.0);
Triangle triang("TriangB", 10.0, 20.0);
cout << "Name is " << rect.getName() << endl;
cout << "Name is "<< triang.getName() << endl;
string rectArea = to_string(rect.calcArea());
string triangArea = to_string(triang.calcArea());
cout << "RectA's area is " << rectArea << endl;
cout << "TriangB's area is " << triangArea << endl;
return 0;
}
And here's my output:
Name is
Name is
RectA's area is 0.000000
TriangB's area is 0.000000
Destroying triangle
Destroying polygon
Destroying rectangle
Destroying polygon
The main problem is that you have variables in the sub classes shadowing the names in the base class - so you assign values to the variables in the base class, but you later print the values of the default initialized variables in the sub classes.
You actually mostly need to remove code.
I would rethink the name of the base class though. Polygon is not a good name for a class with only width and height. I'll leave that up to you.
I've replaced all endl with \n. They do the same thing, but endl flushes the output, which is usually not needed - but it is usually also expensive.
Example:
#include <iostream>
#include <string>
enum Polytype { POLY_PLAIN, POLY_RECT, POLY_TRIANG };
class Polygon {
public:
Polygon(std::string name, double width, double height)
: Polygon(name, width, height, POLY_PLAIN) {}
virtual ~Polygon() { std::cout << "Destroying polygon\n"; }
// make member functions that does not change the object `const`:
virtual Polytype getPolytype() const { return _polytype; }
virtual void setPolytype(Polytype polytype) { _polytype = polytype; }
virtual const std::string& getName() const { return _name; }
// in your case, the implementation could actually be in the base class - but
// I've made it into a pure virtual here.
virtual double calcArea() const = 0; // no instances can be made of Polygon
protected:
// only derived classes can access this constructor:
Polygon(std::string name, double width, double height, Polytype ptype)
: _name(name), _width(width), _height(height), _polytype(ptype) {}
std::string _name;
double _width;
double _height;
Polytype _polytype;
};
class Rectangle : public Polygon {
public:
Rectangle(std::string name, double width, double height)
//use the protected base class ctor:
: Polygon(name, width, height, POLY_RECT) {};
~Rectangle() { std::cout << "Destroying rectangle\n"; }
// the only implementation needed in this sub class:
double calcArea() const override { return _width * _height; }
};
class Triangle : public Polygon {
public:
Triangle(std::string name, double width, double height)
: Polygon(name, width, height, POLY_TRIANG) {};
~Triangle() { std::cout << "Destroying triangle\n"; }
// the only implementation needed in this sub class:
double calcArea() const override { return 0.5 * _width * _height; }
};
int main() {
// Initialize rectangle and triangle and store them onto the stack
Rectangle rect("RectA", 10.0, 20.0);
Triangle triang("TriangB", 10.0, 20.0);
std::cout << "Name is " << rect.getName() << '\n';
std::cout << "Name is " << triang.getName() << '\n';
std::cout << "RectA's area is " << rect.calcArea() << '\n';
std::cout << "TriangB's area is " << triang.calcArea() << '\n';
}
I realized that I did not have to redeclare the private variables in my subclasses. That is probably the reason why it returned null.
#include <iostream>
#include <string>
using namespace std;
enum Polytype {POLY_PLAIN, POLY_RECT, POLY_TRIANG};
class Polygon
{
public:
Polygon(string name, double width, double height){
_name = name;
_width = width;
_height = height;
_polytype = POLY_PLAIN;
}
~Polygon()
{
cout << "Destroying polygon" << endl;
}
virtual Polytype getPolytype(){
return _polytype;
}
virtual void setPolytype(Polytype polytype){
_polytype = polytype;
}
virtual string getName(){
return _name;
}
virtual double calcArea(){
return _width * _height;
}
protected:
string _name;
double _width;
double _height;
Polytype _polytype;
};
class Rectangle: public Polygon
{
public:
Rectangle(string name, double width, double height) : Polygon(name, width, height){
_polytype = POLY_RECT;
};
~Rectangle()
{
cout << "Destroying rectangle" << endl;
}
Polytype getPolytype(){
return _polytype;
}
void setPolytype(Polytype polytype){
_polytype = polytype;
}
double calcArea(){
return _width * _height;
}
string getName(){
return _name;
}
};
class Triangle: public Polygon
{
public:
Triangle(string name, double width, double height) : Polygon(name, width, height){
_polytype = POLY_TRIANG;
};
~Triangle()
{
cout << "Destroying triangle" << endl;
}
Polytype getPolytype(){
return _polytype;
}
void setPolytype(Polytype polytype){
_polytype = polytype;
}
string getName(){
return _name;
}
double calcArea(){
return 0.5 * _width * _height;
}
};
int main(){
//Initialize rectangle and triangle and store them onto the stack
Rectangle rect("RectA", 10.0, 20.0);
Triangle triang("TriangB", 10.0, 20.0);
cout << "Name is " << rect.getName() << endl;
cout << "Name is "<< triang.getName() << endl;
string rectArea = to_string(rect.calcArea());
string triangArea = to_string(triang.calcArea());
cout << "RectA's area is " << rectArea << endl;
cout << "TriangB's area is " << triangArea << endl;
return 0;
}

pointer array of parent class having a pure virtual function and object type of pointer array

here in the main function i want to make a pointer array. object type should change every time.
Something like this.
shape* a[10]=new rectangle;
but i want to make a[0] rectangle type. a[1] circle type and so on.
class shape
{
public:
virtual float boundary_length()=0;
};
class rectangle: public shape
{
public:
float boundary_length()
{
cout<<"Boundary length of rectangle"<<endl;
return 2*(length+width);
}
};
class circle: public shape
{
public:
float boundary_length()
{
return 2*(3.14*radius);
}
};
class triangle: public shape
{
float boundary_length()
{
return (base+perp+hyp);
}
};
int main()
{
shape* a=new rectangle;
return 0;
}
If I have understood you correctly you need something like the following
#include <iostream>
class shape
{
public:
virtual float boundary_length() const = 0;
virtual ~shape() = default;
};
class rectangle: public shape
{
public:
rectangle( float length, float width ) : length( length ), width( width )
{
}
float boundary_length() const override
{
return 2*(length+width);
}
protected:
float length, width;
};
class circle: public shape
{
public:
circle( float radius ) : radius( radius )
{
}
float boundary_length() const override
{
return 2*(3.14*radius);
}
private:
float radius;
};
//...
int main(void)
{
const size_t N = 10;
shape * a[N] =
{
new rectangle( 10.0f, 10.0f ), new circle( 5.0f )
};
for ( auto s = a; *s != nullptr; ++s )
{
std::cout << ( *s )->boundary_length() << '\n';
}
for ( auto s = a; *s != nullptr; ++s )
{
delete *s;
}
}
The program output is
40
31.4

What is the best way to call a derived class's function that isn't part of the base class?

Given the following piece of code:
(This is mostly about what is happening in the Function() method, the rest is just setup/context.)
enum class class_type { a, b };
class Base {
public:
Base(class_type type) : type(type) {}
class_type type;
};
class DerivedA : public Base {
public:
DerivedA() : Base(class_type::a) {}
void FunctionA() {}
};
class DerivedB : public Base {
public:
DerivedB() : Base(class_type::b) {}
void FunctionB() {}
};
void Function(Base& base) {
switch (base.type) {
case class_type::a: {
DerivedA& temp = (DerivedA&)base; // Is this the best way?
temp.FunctionA();
break;
}
case class_type::b: {
base.FunctionB(); // This obviously doesn't work.
break;
}
}
}
int main() {
DerivedA derived_class;
Function(derived_class);
}
Is the way I'm doing it here with DerivedA the best/most efficient way to do it? I feel like there is a better method of doing this, but I don't know how.
The answer is You DON'T do that, it totally handled by the polymorphism, read this code:
And try to map it to your code:
Shap is your Base
Rectangle is your DerivedA
Triangle is your DerivedB
#include <iostream>
using namespace std;
class Shape {
protected:
int width, height;
public:
Shape( int a = 0, int b = 0){
width = a;
height = b;
}
int area() {
cout << "Parent class area :" <<endl;
return 0;
}
};
class Rectangle: public Shape {
public:
Rectangle( int a = 0, int b = 0):Shape(a, b) { }
int area () {
cout << "Rectangle class area :" <<endl;
return (width * height);
}
};
class Triangle: public Shape {
public:
Triangle( int a = 0, int b = 0):Shape(a, b) { }
int area () {
cout << "Triangle class area :" <<endl;
return (width * height / 2);
}
};
// Main function for the program
int main() {
Shape *shape;
Rectangle rec(10,7);
Triangle tri(10,5);
// store the address of Rectangle
shape = &rec;
// call rectangle area.
shape->area();
// store the address of Triangle
shape = &tri;
// call triangle area.
shape->area();
return 0;
}
This is far enough for what you need:
DerivedA& temp = static_cast<DerivedA&>(base);
temp.FunctionA();
Under the hood, this is the same as the C Style cast that you just did, but it's considered a good practice to make them explict.

Sorting vector of objects with operator overloading in c++

I have one base class and I have 4 class derived.of course I write 2 class for example.
I created vector and fill it by objects of derived classes, then I want sort my vector base of area function. I want use operator overloading.
I define operator overloading but it not Completely!
please help me!
Thanks....
class Shape
{
public:
Shape() {}
virtual void draw() = 0;
virtual int area() = 0;
virtual void perimeter() = 0;
bool operator >(Shape * shape_one , Shape* shape_two )
{
return shape_one->area() > shape_two->area();
}
protected :
double height;
double width;
};
class Squar : public Shape
{
public:
Squar(int _width) {
width = _width;
}
void draw(){}
int area(){
return width * width;
}
void perimeter(){}
bool operator >(Squar * squar_one , Squar* squar_two )
{
return squar_one->area() > squar_two->area();
}
};
class Triangle : public Shape
{
public:
Triangle(int _width , int _height) {
width = _width;
height = _height;
}
void draw(){}
int area(){
return (width * height) / 2;
}
void perimeter(){}
bool operator >(Triangle * triangle_one , Triangle* triangle_two )
{
return triangle_one->area() > triangle_two->area();
}
};
int main()
{
Shape *rect = new Rectangular( 1 , 9);
Shape *squar = new Squar(5);
QVector <Shape *> list;
list.push_back(rect);
list.push_back(squar);
retuurn 0;
}
I understand answer the question.
add following code in base class :
bool operator <( Shape *item )
{
return this->area() < item->area();
}
and add following code in main :
std ::sort(list.begin() , list.end() ,[](Shape* ptr_l , Shape* ptr_r) { return *ptr_l < ptr_r;} );
This code is correct! :)