Accessing Object names from Array

Using inheritance classes, I am looking to calculate the area of 2d shapes and area and volume of 3d shapes. I am now need to access the array determine the shape and then determine whether to calculate the area or the volume of the shape. The end goal is to loop through and provide output saying the name of the shape the area and/or the volume. How do I access the object names of the array? Thanks
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#ifndef SHAPE_H
#define SHAPE_H

const double PI = 3.14159265359;
//Base Class---------------------------------------------
Class Shape {
	protected:
		//Dimensions
		int dimensions;
		double area;
		double volume;
	public:
		//Default Constructor
		Shape();
		//Destructor
		~Shape();
		//Get Dimension function
		double getDimensions();
		//virtual function
		virtual double getArea();
		virtual double getVolume();
};
//Shape Type-----------------------------------------------
class TwoDimensionalShape : public Shape {
	protected:
		double d1, d2;
	public:
		double get_d1() { return d1; }
		double get_d2() { return d2; }
		double set_d1(double x) { d1 = x; }
		double set_d2(double x) { d2 = x; }
};
class ThreeDimensionalshape : public Shape {
	protected:
		double d1, d2, d3;
	public:
		double get_d1() { return d1; }
		double get_d2() { return d2; }
		double get_d3() { return d3; }
		double set_d1(double x) { d1 = x; }
		double set_d2(double x) { d2 = x; }	
		double set_d3(double x) { d3 = x; }	
};
//two dimensionals Shape classes-------------------------
class Circle : public TwoDimensionalShape {
	public:
		Circle(); //default constructor
		Circle( double r); //regular constructor
		double getArea(); //get area function
};
class Square : public TwoDimensionalShape {
	public:
		Square();
		Square(double dim);
		double getArea(); 
};
class Triangle : public TwoDimensionalShape {
	public:
		Triangle();
		Triangle(double dim, double dim2); 
		double getArea(); 
};
//three dimensional shape classes-------------------------
class Sphere : public ThreeDimensionalshape {
	public:
		Sphere();
		Sphere(double dim);
		double getArea();
		double getVolume();
};
class Cube : public ThreeDimensionalshape{
	public:
		Cube();
		Cube(double dim);
		double getArea();
		double getVolume();	
};
class Tetrahedron : public ThreeDimensionalshape{
	public:
		Tetrahedron();
		Tetrahedron(double dim);
		double getArea();
		double getVolume();
};

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include <stdlib.h>
#include <cmath.h>

#include "shape.h" //header file

using namespace std;
//----------------------------------------------
//Default constructor
Shape::Shape() : dimensions(0), area(0), volume(0) { }
//Regular constructor
Shape::Shape(int d) : {
	dimensions = d;
}
//Function getDimensions
double Shape::getDimensions() {
	return dimensions;
}

//Two dimensional shapes-----------------------------------
//Default constructor--------------------
Circle::Circle() { 
	d1 = 1 ;
}
//Regular constructor--------------------
Circle::Circle( double r ) {
	d1 = r;
}
//Circle area
double Circle::getArea() {
	area = PI * pow( d1, 2 );
	return area;
}
//Default constructor--------------------
Square::Square() {
	d1 = 1 ;
	d2 = 1;
}
//Regular constructor--------------------
Square::Square( double dim ){
	d1 = dim;
	d2 = dim;
}
//Square area
double Square::getArea(){
	area = pow( d1, 2 );
	return area;
}
//Default constructor--------------------
Triangle::Triangle(){
	d1 = 1;
	d2 = 1;
}
//Regular constructor--------------------
Triangle::Triangle(double dim, double dim2){
	d1 = dim;
	d2 = dim2;
}
//Triangle area
double Triangle::getArea(){
	area = (d1 * d2) / 2;
}
//Three dimensional shapes-----------------------------------
//Default constructor---------------------
Sphere::Sphere(){
	d1 = 1;
	d2 = 1;
	d3 = 1;
}
//Regular constructor---------------------
Sphere::Sphere(double dim) : {
	d1 = dim;
	d2 = dim;
	d3 = dim;
}
//Sphere area
double Sphere::getArea(){
	area = 4 * PI * pow( d1, 2 );
	return area;
}
//Sphere volume
double Sphere::getVolume(){
	volume = (4/3) * PI * pow( d1, 3 );
	return volume;
}
//Default constructor---------------------
Cube::Cube(){
	d1 = 1;
	d2 = 1;
	d3 = 1;
}
//Regular constructor---------------------
Cube::Cube(double dim){
	d1 = dim;
	d2 = dim;
	d3 = dim;
}
//Cube area
double Cube::getArea(){
	area = pow( d1, 2 );
	return area;
}
//Cube Volume
double Cube::getVolume(){
	volume = pow( d1, 3 );
	return volume;
}
//Default constructor---------------------
Tetrahedron::Tetrahedron(){
	d1 = 1;
	d2 = 1;
	d3 = 1;
}
//Regular constructor---------------------
Tetrahedron::Tetrahedron(double dim){
	d1 = dim;
	d2 = dim;
	d3 = dim;
}
//tetrahedron area
double Tetrahedron::getArea(){
	area = sqrt(3) * pow( d1, 2);
	return area;
}
//tetrahedron volume
double Tetrahedron::getVolume(){
	volume = pow(d1, 3) / (6 * sqrt(2));
	return volume;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <stdlib.h>
#include <cmath.h>

#include "shape.h" //header file

using namespace std;

int main() {
//Pointer Array--------------------------------------------
	Shape* arr[6];
//Assign Shape Dimensions and to Array
	Circle cir(2);  //declares value for circle ~ cir is var name
		arr[0] = &cir; //assigns cir var to array position 0
	Square sqr(3);
		arr[1] = &sqr;
	Triangle tri(4, 2);
		arr[2] = &tri;	
	Sphere sph(5);
		arr[3] = &sph;
	Cube cb(6);
		arr[4] = &cb;
	Tetrahedron trhd(7);
		arr[5] = &trhd;
//Loop each index of array and perform calculation
	for (int i = 0; i < 6; ++i)
	{
		cout << ""
	}
}

Last edited on
closed account (D80DSL3A)
Since you're using an array of Shape*s, you can access only functions defined through the base class.
These are:
1
2
3
4
5
//Get Dimension function
double getDimensions();
//virtual function
virtual double getArea();
virtual double getVolume();

The virtual functions should be pure virtual though. They can't be defined until the instantiable classes ( Circle, Square, Triangle, etc...) are reached. getDimensions() can be defined in the base class.

getVolume() will need a definition, even in the TwoDimensionalShape classes.
For 2D shapes perhaps this is reasonable?
virtual double getVolume(){ return 0.0; }// 2D shapes have volume = 0

Also, what is role of int dimensions data member? Is it = 2 or 3 to indicate # of spatial dimensions?

Remember, sub-objects are constructed first, so a good place to define these 2D attributes is in your intermediate TwoDimensionalShape and ThreeDimensionalShape classes.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
//Base Class---------------------------------------------
Class Shape {
	protected:
		//Dimensions
		int dimensions;// assign in derived class?
		double area;// purpose?
		double volume;// purpose?
	public:
		//Default Constructor
		Shape();
		//Destructor
		~Shape();
		//Get Dimension function
		double getDimensions();
		//virtual function
		virtual double getArea() = 0;
		virtual double getVolume() = 0;
                virtual std::string getName() = 0;// added to solve naming issue
};
//Shape Type-----------------------------------------------
class TwoDimensionalShape : public Shape {
	protected:
		double d1, d2;
	public:
                TwoDimensionalShape() : dimensions(2) {  }// added constructor
                virtual double getVolume() { return 0.0; }// covered for all 2D shape types now

		double get_d1() { return d1; }
		double get_d2() { return d2; }
		double set_d1(double x) { d1 = x; }
		double set_d2(double x) { d2 = x; }
};
class ThreeDimensionalshape : public Shape {
	protected:
		double d1, d2, d3;
	public:
                ThreeDimensionalShape() : dimensions(3) {  }// added constructor
		double get_d1() { return d1; }
		double get_d2() { return d2; }
		double get_d3() { return d3; }
		double set_d1(double x) { d1 = x; }
		double set_d2(double x) { d2 = x; }	
		double set_d3(double x) { d3 = x; }	
};

Define all 3 pure virtual functions in classes derived from ThreeDimensionalShape, and all but getVolume() in those derived from TwoDimensionalShape.
Just return the literal string name of each object, eg.
 
std::string Circle::getName() { return std::string("Circle"); }

Finally, you can call what's needed in main:
1
2
3
4
5
6
7
//Loop each index of array and perform calculation
	for (int i = 0; i < 6; ++i)
	{
		cout << '\n' << arr[i]->getName() << " with area = " << arr[i]->getArea();
                if( arr[i]->dimensions == 3 )
                     cout << " and volume = " << arr[i]->getVolume();
	}
Last edited on
Hi,

Pretty good effort for your code :+)

You already have all the stuff you need for polymorphism, just call the function - the compiler will do the right thing:

24
25
26
27
28
//Loop each index of array and perform calculation
	for (int i = 0; i < 6; ++i)
	{
		cout << "Area is " << arr[i]->getArea() << "\n";
	}


To print the name of each shape, put a virtual function in the Shape class - getName() (along with a string Name variable) and override it in all the derived classes.

Some extra things, maybe a little advanced:

Mark all of your get functions const, they don't change the state of the class, that is don't change any values of the member variables.

Parameters in your constructors should be const as well, the compiler can enforce the idea that you won't change the argument's value in the function.

When you override a virtual function, use the c++11 override keyword, here is one example - you should do it for all of them in the header files:

45
46
47
48
49
50
class Circle : public TwoDimensionalShape {
	public:
		Circle(); //default constructor
		Circle( double r); //regular constructor
		double getArea() override;  //get area function
};


The virtual functions in the Shape class could be pure virtual, forcing them to be overriden in the derived classes.

Probably shouldn't have protected member data, I know it's easy, but member data should be private. You already have member functions to retrieve their values.

You can use a member initialization list rather than assignment to set values in your constructor:

1
2
3
4
5
6
7
//Regular constructor--------------------
Triangle::Triangle(const double dim, 
                          const double dim2)
     : // colon introduces a member init list
      d1(dim),  // direct initialization, avoids intialization, copying
      d2(dim2) // then assignment again
{}


Good Luck !!
Last edited on
Topic archived. No new replies allowed.