Unable to access the base variables in the derrived class - c++

The following compiled code is showing the resulting area of zero. Some how the width and height variables are still remaining as zero even though we set it using the base constructor.
#include <iostream>
using namespace std;
class Shape {
protected:
int width, height;
public:
Shape( int a=0, int b=0)
{
width = a;
height = b;
}
virtual 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 << "Rectangle 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.
cout << shape->area() << endl;
// store the address of Triangle
shape = &tri;
// call triangle area.
cout << shape->area() << endl;
return 0;
}
Output:
Rectangle class area :
0
Rectangle class area :
0
Trying to find out why the area is zero and how to make the pgm to print the actual area ?

The correct syntax is:
Rectangle( int a=0, int b=0) : Shape(a, b)
{ // ^^^^^^^^^^^^
}
You need to call Shape constructor as part of initializer list.
As in your example, if you write it as a statement,
{
Shape(a,b); // <--- no effect on Base part
}
then, a temporary Shape object is created and destroyed, so it has no effect.

your constructor of child class should be like following,
Rectangle( int a=0, int b=0)
:Shape(a, b) //call base class constructor
{
//Shape(a, b); // you are creating new object of shape here , not calling base constructor
}

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;
}

Using Initializer List in Polymorphism in C++ creating confusion as in place of variable a class is used

#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);
}
};
int main() {
Shape *shape;
Rectangle rec(10,7);
Triangle tri(10,5);
shape = &rec;
shape->area();
shape = &tri;
shape->area();
return 0;
}
in this example I am not able to understand the function of
Rectangle( int a = 0, int b = 0):Shape(a, b) { }
and
Triangle( int a = 0, int b = 0):Shape(a, b) { }
I understand this is similar to the syntax of Initializer List in C++, but with Initializer List we can intialize any variable like
class_apple (int var) : x(var) {}
so here x=var, but in above code in place of the variable
:Shape(a, b)
the Shape class is used? what does this achieve and what does it mean for polymorphism?
Rectangle( int a = 0, int b = 0) : Shape(a, b) { }
Rectangle is a derived class of Shape. :Shape(a,b) passes the arguments a and b, received by the Rectangle constructor to its base class.
When a Rectangle instance is created it uses Shape(int a, int b) constructor to assign values to width and height.
The same is true with Triangle since it too derives from Shape.
Now consider the following hierarchy.
struct Base {
int x,y;
Base(int a, int b) : x(a), y(b) {}
};
struct Derived : Base {
int m;
Derived(int a, int b, int c) : Base(a, b), m(c) {}
};
In the above example Derived class passes arguments a and b to the base class constructor while using the member initialization list to initialize m with the value of c.

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.

Pointer to different components of a class

I have an assignment from school to create pointers to different components of a class.
I don't understand how it works. Can someone help me with a simple program?
I have made the basic layout of what's needed. I don't know how to go about creating pointers.
#include <iostream>
#include <math.h>
using namespace std;
class Rectangle
{
int a,b;
public:
};
class Perimeter : public Rectangle
{
public:
int c;
void P(int a, int b)
{
c = 2 * (a + b);
cout << "This Is The Perimeter Of The Rectangle: " << c << endl;
}
};
class Area : public Rectangle
{
public:
int c;
void A(int a, int b)
{
c = a * b;
cout << "This Is The Area Of The Rectangle: " << c << endl;
}
};
class Diagonal : public Rectangle
{
public:
float c;
void D(int a, int b)
{
c = sqrt((a*a)+(b*b));
cout << "This Is The Diagonal Of Rectangle: " << c << endl;
}
};
#include<iostream>
#include<math.h>
using namespace std;
class Rectangle
{
int a,b;
public:
};
class Perimeter : public Rectangle
{
public:
int c;
void P(int a, int b)
{
c = 2 * (a + b);
cout<<"This Is The Perimeter Of The Rectangle: "<<c<<endl;
}
};
class Area : public Rectangle
{
public:
int c;
void A(int a, int b)
{
c = a * b;
cout<<"This Is The Area Of The Rectangle: "<<c<<endl;
}
};
class Diagonal : public Rectangle
{
public:
float c;
void D(int a, int b)
{
c = sqrt((a*a)+(b*b));
cout<<"This Is The Diagonal Of Rectangle: "<<c<<endl;
}
};
int main()
{
int e,f;
cout<<"Enter Length And Breadth: "<<endl;
cin>>e>>f;
/***************************************/
Perimeter p; //CREATING AN OBJECT
Perimeter *Peri; //CREATING A POINTER TO THE OBJECT
Peri=&p; //ASSIGNING ADDRESS TO THE POINTER
Peri->P(e,f); //MEMBER ACCESS USING POINTER TO AN OBJECT
/**************************************/
Area a;
int Area::*ptr=&Area::c; //CREATING A POINTER TO THE DATA MEMBER
a.*ptr = e;
a.A(e,f);
/*************************************/
Diagonal d;
void (Diagonal::*Dia)(int,int)=&Diagonal::D; //CREATING POINTER TO MEMBER FUNCTION
(d.*Dia)(e,f); //THIS IS HOW WE CALL THE MEMBER FUNCTION USING ITS POINTER
/*************************************/
return 0;
}
I believe this is what you were looking for.
there are some errors you made in the program. i didn't correct them but i am pointing them out.
though you didn't write anything(create any functions) in the parent class, creating pointer to an object of the sub-class is useless. in this case, early binding is taking place. you can go with a pure virtual function following function Over-Riding.
A pointer is a reference to an area in memory.
In the picture, foo is holds the value 1702 which is the spot in memory the string "hello" is stored. Pointers to elements in a class work the same way. Your class will occupy some part of memory and a pointer to the class member will hold the value of where the class member is in memory.
I'm not sure which type of pointer you're supposed to use for your class, but there's three different types.
Raw pointers:
These are the types similar to shown in the picture. An example would be:
int * x = 5; // Let's say 5 is stored at memory location 0x15
cout << x; // This will give 0x15
cout << *x; // This "dereferences" the pointer also known as go to that memory location and retrieve the value. This outputs 5
There are also Smart Pointers as defined here:
https://learn.microsoft.com/en-us/cpp/cpp/smart-pointers-modern-cpp?view=vs-2019
These are meant to be safer since they will be garbage collected, and prevent common dereferencing errors.
For using pointers in a class it could be as easy as:
class shape {
int * height;
int * width;
public:
void setHeight (int x) {height = &x; }
void setWidth(int x) { width = &x; }
int getHeight(){ return *height; }
int getWidth() { return *width; }
};
class square : class shape {
public getArea(int *h, int *w) {returns *h * *w; }
};
int main {
int x = 5;
int y = 6;
int * pointerX = &x; //& means this variable's memory address
int * pointerY = &y;
rect rectangle;
std::cout << rectangle.getArea(pointerX, pointerY) << std::endl;
rectangle.setHeight(7);
std::cout << "Rect height:" << rectangle.getHeight() << std::endl;
rectangle.setWidth(9);
std::cout << "Rect width:" << rectangle.getWidth() << std::endl;
rect * ptrRect = &rectangle;
std::cout << ptrRect->getArea(pointerX, pointerY) << std::endl;
ptrRect->setHeight(9);
std::cout << "ptrRect height:" << ptrRect->getHeight() << std::endl;
ptrRect->setWidth(10);
std::cout << "ptrRect width:" << ptrRect->getWidth() << std::endl;
std::cout << square.getArea(pointerX, pointerY) << std::endl;
}

Polymorphism vs Inheritance. Diffrence?

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.