'Copy child object to parent object
I have three classes: Shape
, Rectangle
and Circle
. Shape
is parent of two other class. definition of this classes is in following code:
#include <iostream>
using namespace std;
class Shape {
public:
Shape() {
}
~Shape() {
}
void set(float BORDER, string COLOR) {
border = BORDER;
color = COLOR;
}
double computeArea() {
return 0;
}
private:
float border;
string color;
};
class Circle : public Shape {
public:
Circle() {
}
~Circle() {
}
void setRadius(float RADIUS) {
radius = RADIUS;
}
double computeArea() {
return 3.14 * radius * radius;
}
private:
float radius;
};
class Rectangle : public Shape {
public:
Rectangle() {
}
~Rectangle() {
}
void setWidth(float w) {
width = w;
}
void setLength(float l) {
length = l;
}
double computeArea() {
return width * length;
}
private:
float width;
float length;
};
I build two object from Circle
and Rectangle
classes. Then I copied this two object into Shape
class. When I run computeArea()
function in following order I get 0
result.
#include <iostream>
using namespace std;
int main() {
Circle c;
c.setRadius(3);
Rectangle r;
r.setWidth(4);
r.setLength(5);
Shape sh[2];
sh[0] = c;
sh[1] = r;
cout << sh[0].computeArea() << endl;
cout << sh[1].computeArea();
return 0;
}
I want compute area of all shapes with correct function. How can I do that?
Thanks in Advance
Solution 1:[1]
To expand on what Fureeish said, change your code to this:
int main() {
Circle c;
c.setRadius(3);
Rectangle r;
r.setWidth(4);
r.setLength(5);
Shape *sh[2];
sh[0] = &c;
sh[1] = &r;
cout << sh[0]->computeArea() << endl;
cout << sh[1]->computeArea();
return 0;
}
and declare computeArea
(and also Shape
's destructor, in case you destroy a derived object through a pointer to the base class) as virtual
.
Assigning a derived class to an object of the base class is known as 'object slicing' and usually leads to undesirable results. Using pointers (or references) avoids this.
Solution 2:[2]
In Shape class make computeArea() an abstract(or purely virtual) method:
virtual double computeArea() =0;
Solution 3:[3]
You seem to be missing the virtual
keyword.
The destructor of the base class Shape needs to be virtual as well (in case you ever decide to manipulate any of the derived objects through a pointer to the base class).
The function computeArea() must be declared virtual, like this virtual double computeArea() { ... }
.
#include <iostream>
using namespace std;
class Shape {
public:
Shape() {
}
virtual ~Shape() {
}
void set(float BORDER, string COLOR) {
border = BORDER;
color = COLOR;
}
virtual double computeArea() {
return 0;
}
private:
float border;
string color;
};
class Circle : public Shape {
public:
Circle() {
}
virtual ~Circle() {
}
void setRadius(float RADIUS) {
radius = RADIUS;
}
virtual double computeArea() {
return 3.14 * radius * radius;
}
private:
float radius;
};
class Rectangle : public Shape {
public:
Rectangle() {
}
virtual ~Rectangle() {
}
void setWidth(float w) {
width = w;
}
void setLength(float l) {
length = l;
}
virtual double computeArea() {
return width * length;
}
private:
float width;
float length;
};
Also if you are using C++11 or newer, you can add the overrride
keyword at endd of the computeArea
function definitions, like this
virtual double computeArea() override {
return width * length;
}
and this,
virtual double computeArea() override {
return 3.14 * radius * radius;
}
in the respective classes.
And then modify the main function like this.
int main() {
Circle c;
c.setRadius(3);
Rectangle r;
r.setWidth(4);
r.setLength(5);
Shape *sh1, *sh2;
sh1 = &c;
sh2 = &r;
cout << sh1->computeArea() << endl;
cout << sh2->computeArea();
return 0;
}
EDIT: Also, as others have pointed out, you need pointers to the base class and don't need to copy your derived class objects to the base class object. See the modified main() function please.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Salma Halloumi |
Solution 3 |