I am getting this annoying error and I don't know why =( !
This is the question , I solved it but I am having a problem with the constructor.
Write a program that defines a class called Circle that includes radius (type double) as data members. Provide a set and a get function
for this data member. Ensure that the value entered by the user is
valid and correct (greater than zero).
Include function members: a.function member that compute and return Diameter of the circle b.function member that compute and
return Circumference of the circle c.function member that compute and
return Area of the circle d.function member that Display all
information of the circle e.constructor that initializes the data
member. If the radius is not valid (i.e. less than zero) set it to
zero.
the error I am facing :
error C2512: 'Circle' : no appropriate default constructor available
this is my code :
#include <iostream>
using namespace std;
class Circle
{
public:
Circle(double);
void setRadius(double);
double getRadius();
void Display();
double Diameter(double);
double Circumference(double);
double Area(double);
private:
double radius;
};
Circle::Circle(double radio)
{
setRadius(radio);
}
void Circle::setRadius(double ra)
{
if (ra < 0)
{
radius = 0;
}
else
radius = ra;
}
double Circle::getRadius()
{
double rado;
cout << "Enter the Radius:\n";
cin >> rado;
setRadius(rado);
return radius;
}
double Circle::Diameter(double rad)
{
return 2*rad;
}
double Circle::Area(double radi)
{
return 3.14 * radi * radi;
}
double Circle::Circumference(double radiu)
{
return 2 * 3.14 * radiu;
}
void Circle::Display()
{
cout << "The Radius of the circle is: \n";
cout << radius;
cout << "\nThe Diameter of the circle is: \n";
cout << Diameter(radius);
cout << "\nThe Circumference of the circle is: \n";
cout << Circumference(radius);
cout << "\nThe Area of the circle is: \n";
cout << Area(radius);
cout << endl;
}
int main()
{
Circle C;
C.getRadius();
C.Display();
return 0;
}
This line invokes a constructor with no arguments (known as default constructor):
Circle C;
The only constructor you have defined is:
Circle(double);
Hopefully this should point you in the right direction.
A default constructor is one without any parameters. Normally, it is provided for you. But if you explicitly define any other constructor, then it is not. So you have to define it yourself, or not use it. You are using it when you create an object in main, like this:
Circle C;
So, either define a default constructor, or don't use it.
Well, then add one :)
Circle() : radius(0.0) {}
You should define a constructor with no parameters called default constructor. You can initialize related members to the default values.
Circle::Circle()
{
radius = 0.0
}
Related
Im practicing memberwise assignment in C++, where you can set the values of one object to another object of the same class. The idea of the program is to initialize a rectangle object with some values and create another rectangle object but assign the value of the first into the second.
Its giving me an error, which is posted below, and I can't figure out what it is and its driving me nuts lol
This is my Rectangle.h
#ifndef RECTANGLE_H
#define RECTANGLE_H
class Rectangle {
private:
double length;
double width;
public:
Rectangle(double, double);
double getLength() const;
double getWidth() const;
};
Rectangle::Rectangle(double l, double w) {
length = l;
width = w;
}
double Rectangle::getWidth() const { return width; }
double Rectangle::getLength() const { return length; }
#endif
This is my Rectangle.cpp
#include <iostream>
#include "rectangle.h"
using namespace std;
int main()
{
Rectangle box1(10.0, 10.0);
Rectangle box2;
cout << "box1's width and length: " << box1.getWidth() << ", " << box1.getLength() << endl;
cout << "box2's width and length: " << box2.getWidth() << ", " << box2.getLength() << endl;
box2 = box1;
cout << "box1's width and length: " << box1.getWidth() << ", " << box1.getLength() << endl;
cout << "box2's width and length: " << box2.getWidth() << ", " << box2.getLength() << endl;
return 0;
}
This is the error when I compile.
skipper~/Desktop/Programming/Memberwise: g++ rectangle.cpp
rectangle.cpp:7:12: error: no matching constructor for initialization of
'Rectangle'
Rectangle box1(10.0, 10.0);
^ ~~~~~~~~~~
./rectangle.h:4:7: note: candidate constructor (the implicit copy constructor)
not viable: requires 1 argument, but 2 were provided
class Rectangle {
^
./rectangle.h:4:7: note: candidate constructor
(the implicit default constructor) not viable: requires 0 arguments, but 2
were provided
1 error generated.
EDIT: This is how I was able to make it work. I moved everything into rectangle.cpp and gave the constructor default arguments.
EDITED rectangle.cpp
#include <iostream>
using namespace std;
class Rectangle {
private:
double length;
double width;
public:
//Rectangle();
Rectangle(double = 0.0, double = 0.0);
double getLength() const;
double getWidth() const;
};
int main()
{
Rectangle box1(10.0, 10.0);
Rectangle box2;
cout << "box1's width and length: " << box1.getWidth() << ", " << box1.getLength() << endl;
cout << "box2's width and length: " << box2.getWidth() << ", " << box2.getLength() << endl;
box2 = box1;
cout << "box1's width and length: " << box1.getWidth() << ", " << box1.getLength() << endl;
cout << "box2's width and length: " << box2.getWidth() << ", " << box2.getLength() << endl;
return 0;
}
Rectangle::Rectangle(double l, double w) {
length = l;
width = w;
}
double Rectangle::getWidth() const { return width; }
double Rectangle::getLength() const { return length; }
The only changes I made were giving default arguments to my user-defined constructor. However, it wasn't able to work when the changes were in rectangle.h. However, when I moved the class and member function definitions to rectangle.cpp it was able to work. So, I got the program to work but I didn't address the real issue, which is when the class and member function definitions are in rectangle.h, it won't compile.
If anyone has faced this problem and has found a solution to this, please let me know how you did it. Thanks :)
In the line
Rectangle box2; // no default constructor, error
you are trying to invoke the default constructor of Rectangle. The compiler does not generate such a default constructor anymore, because your Rectangle has a user defined constructor that takes 2 parameters. Therefore, you need to specify the parameters, like
Rectangle box2(0,10);
The error I get when compiling your code is:
Rectangle.cpp:8:15: error: no matching function for call to 'Rectangle::Rectangle()'
Rectangle box2;
A solution is to create a default constructor for Rectangle, since it is not automatically generated anymore due to your user defined one:
Rectangle(); // in Rectangle.h
Rectangle::Rectangle(){} // in Rectangle.cpp (or Rectangle::Rectangle() = default; in C++11)
Another solution (and the preferable one, since it doesn't leave the data un-initialized) is to assign default arguments to your existing constructor.
Rectangle::Rectangle(double l = 0, double w = 0); // only in Rectangle.h
In this way, you make your class Default-Constructible.
A compiler generated default constructor is only generated if you have no defined constructors. You define a constructor, so if you want a default constructor you have to provide it yourself. Probably the easiest (arguably) is to provide it by using default arguments in your two argument constructor:
Rectangle(double l=0, double w=0)
Also you should use the inline keyword as shown below or you may find you get linker errors:
inline Rectangle::Rectangle(double l, double w) {
length = l;
width = w;
}
inline double Rectangle::getWidth() const { return width; }
inline double Rectangle::getLength() const { return length; }
I am trying to call a function in another class. I need to use the surface area function or the information that was stored in it from the previous class for another class. How would I go about that?
I have already tried HalfOpenCylinder::surfaceArea() and HalfOpenCylinder.surfaceArea() and neither worked.
//surface area function that I want to use for other class
double HalfOpenCylinder::surfaceArea(double height, double pi) {
double surfaceArea = (2 * pi * radius * height) + (pi * pow(radius, 2));
return surfaceArea;
}
To call a function from another class you need to first create an object (instance) of that class.
Using that object you can call a particular function
eg:
#include <iostream>
using namespace std;
class Student
{ // defining class
public:
int id;
void add(){
int x=1;
int y=2;
int z=x+y;
cout<<z<<endl;
}
};
int main() {
Student s1; // creating object of class
s1.id=20;
s1.add() // calling function of that class
return 0;
}
I have written a script that shows you how you can
"call a function in another class"
and
"use the surface area function or the information that was stored in it from the previous class for another class".
This is a script with many examples in it. It uses an updated version of your surfaceArea() method (method being the term since the function is defined from within a class). I have also included what output the script produces at the very bottom of the script.
You can copy and past this entire code segment into a C++ compiler and it should work for you. I compiled and tested it in Visual Studio 2015 Community. I went to new project, and created a "Win32 Console Application" in the C++ category.
// ConsoleApplication10.cpp : Defines the entry point for the console application.
//
// This class example was created to answer kittykoder's question on StackOverflow.
// Both of these need to be included
#include "stdafx.h"
#include <iostream>
// We need the std namespace
using namespace std;
// Here I am defining a struct so that you can easily take all the values out of the
// HalfOpenCylinder class at once, and even make a new Cylinder object with the values by
// using the struct in one of the two HalfOpenCylinder class constructors.
struct CylinderValues
{
public:
CylinderValues(double radius, double height, double surfaceArea) {
this->radius = radius;
this->height = height;
this->surfaceArea = surfaceArea;
}
__readonly double radius;
__readonly double height;
__readonly double surfaceArea;
};
// This is the class I saw in your example. Since it is named
// HalfOpenCylinder, I decided to treat it like an
// instantiatable object class, both because it makes sense name wise,
// and based on the context you provided in your question.
class HalfOpenCylinder
{
public:
// Pi is always 3.14, so there is no reason to make it a passable parameter
// like in your example. Thus I have made it a constant. It's a static constant because
// of the static function I've placed in this class to help in answering your question.
static const float pi;
// I have encapsulated the variables that make up this
// class's objects behind methods so that the surface area can be
// updated every time the radius or height values are changed.
double GetRadius() { return radius; }
void SetRadius(double value) { radius = value; UpdateSurfaceArea(); }
double GetHeight() { return height; }
void SetHeight(double value) { height = value; UpdateSurfaceArea(); }
double GetSurfaceArea() { return surfaceArea; }
// You can make a HalfOpenCylinder object with this constructor
HalfOpenCylinder(double radius, double height) {
this->radius = radius;
this->height = height;
UpdateSurfaceArea();
}
// You can use another HalfOpenCylinder object to make a new HalfOpenCylinder object using
// this constructor.
HalfOpenCylinder(CylinderValues values) {
radius = values.radius;
height = values.height;
surfaceArea = values.surfaceArea;
}
// This will return the struct needed to use the constructor just above this comment.
CylinderValues CopyValues() {
return CylinderValues(radius, height, surfaceArea);
}
// Here is your surface area calculation from your question
static double CalculateSurfaceArea(double radius, double height) {
return (2 * pi * radius * height) + (pi * pow(radius, 2));
}
private:
// Here are the values you wanted to be able to access from another class.
// You can access them using the methods above for getting and setting. The
// surfaceArea value is automatically recalculated if you change either the
// radius or height variable's values.
double radius;
double height;
double surfaceArea;
// This method is here so that HalfOpenCylinder objects can use the
// Surface area calculation. I could have copied and pasted the calculation
// code here to avoid calling the static method, but then I would be writing code
// more than need be. This way, you can update one and the other will be correct.
void UpdateSurfaceArea() {
surfaceArea = CalculateSurfaceArea(radius, height);
}
};
// This is honestly just here because the compiler yelled at me for defining a static
// constant inside a non-static class. Could'a gotten away with it in C#. Thank you compiler.
const float HalfOpenCylinder::pi = 3.141592;
// This is called a function since it is outside of any class (although,
// that is one of the few differences between functions and methods.
// Methods being, functions defined inside classes)
void ThisIsAFunction() {
cout << "This is the text from the function named: ThisIsAFunction";
}
// This class is just here to show you how to call functions and methods from inside classes
class CallFunctionAndMethodTester
{
public:
void MethodInsideTheClass() {
cout << "The below is printed from a function called in a class: \n";
// Here, I am calling a function from inside a class
ThisIsAFunction();
cout << "\n\nThe below is printed from a static method called in a class: \n";
// Here, I am calling a static method from inside a class
cout << HalfOpenCylinder::CalculateSurfaceArea(14.5, 50.5);
// Here, I am making an object instance from inside a class
HalfOpenCylinder bobTheCylinder(1.5, 5.4);
cout << "\n\nThe below is printed from an object's method called in a class: \n";
// Here, I am calling an object's method from inside a class
cout << bobTheCylinder.GetRadius();
}
};
// Ok. We made it. THIS main function is where we will use and
// test the classes we have made above.
int main() {
// Make a new cylinder object. No pointer, so it will be destroyed when the computer
// reads past main (which is the end of this program anyways).
cout << "Cylinder 1 Values: \n";
HalfOpenCylinder cylinder1(5.0, 10.0);
cout << cylinder1.GetRadius();
cout << "\n"; // <--just makin' a newline here
cout << cylinder1.GetHeight();
cout << "\n";
cout << cylinder1.GetSurfaceArea();
cout << "\n\n"; // <--just makin' two newlines here
// Change the object's height. The surface area updates automatically.
cout << "Cylinder 1 new surface area once Height is changed: \n";
cylinder1.SetHeight(20.5);
cout << cylinder1.GetSurfaceArea();
cout << "\n\n";
// Make a second Cylinder using the first cylinder's values.
cout << "Cylinder 2 Values: \n";
HalfOpenCylinder cylinder2(cylinder1.CopyValues());
cout << cylinder2.GetRadius();
cout << "\n";
cout << cylinder2.GetHeight();
cout << "\n";
cout << cylinder2.GetSurfaceArea();
cout << "\n\n";
// Here I'm using the static CalculateSurfaceArea function to use the surface area
// method without having to make a new HalfOpenCylinder object.
cout << HalfOpenCylinder::CalculateSurfaceArea(5.0, 10.0);
cout << "\n\n";
// Here I am making an object of type CallFunctionAndMethodTester so that I can call
// the method inside it that is using my example of how to call functions and methods
// from within classes.
CallFunctionAndMethodTester tester;
cout << "Everything printed to the console after this line is printed using functions and methods that are called from inside classes. \n\n";
tester.MethodInsideTheClass();
int meh;
cin >> meh;
return 0;
}
/* Here is the output of this code when the program runs:
Cylinder 1 Values:
5
10
392.699
Cylinder 1 new surface area once Height is changed:
722.566
Cylinder 2 Values:
5
20.5
722.566
392.699
Everything printed to the console after this line is printed using functions and methods that are called from inside classes.
The below is printed from a function called in a class:
This is the text from the function named: ThisIsAFunction
The below is printed from a static method called in a class:
5261.38
The below is printed from an object's method called in a class:
1.5
*/
I'm new to C++
below is the code for converting object of english distance(feet' inches") to meters and vice versa
#include <iostream>
using namespace std;
class Distance
{
private:
const float MTF;
int feet;
float inches;
public:
Distance() : feet(0), inches(0.0), MTF(3.280833F) //no argument constructor
{ }
Distance(float meters) : MTF(3.28033F)//(1-arg constructor)
{//coverting metres to distance object
float fltfeet = MTF * meters;
feet = int(fltfeet);
inches = 12*(fltfeet-feet);
}
Distance(int ft, float in) : feet(ft), inches(in), MTF(3.280833F)
{ }
void getdist()//get distance from user
{
cout << "\nEnter feet: "; cin >> feet;
cout << "Enter inches: "; cin >> inches;
}
void showdist() const // o/p the distance
{ cout << feet << "\'-" << inches << '\"'; }
operator float() const //conversion operator
{ // converts distance to meters
float fracfeet = inches/12;
fracfeet += static_cast<float>(feet);
return fracfeet/MTF;
}
};
int main()
{
float mtrs;
Distance dist1 = 2.35F; //meters to distance
cout << "\ndist1 = "; dist1.showdist();
mtrs = static_cast<float>(dist1); //casting distance to meters
cout << "\ndist1 = " << mtrs << " meters\n";
Distance dist2(5, 10.25);
mtrs = dist2; //casting dist2 to meters
cout << "\ndist2 = " << mtrs << " meters\n";
Distance dist3; //new object dist3
dist3 = mtrs; //here is the error
//not converting meters to distance object
cout<<"\ndist3 = ";dist3.showdist();
return 0;
}
but the code shows the error :
In member function 'Distance& Distance::operator=(const Distance&)':
error: non-static const member 'const float Distance::MTF', can't use default assignment operator
should'nt it be converting mtrs to object dist3 ?
why error occurs?
You error is actually with the line
dist3 = mtrs;
not
Distance dist3;
The reason for this is Distance has a const member variable. Since it is const it cannot be assigned to which cause the default copy assignment and move assignment operators to be deleted.
You are going to have to rethink your design if you want to allow assignment of your objects or write your own custom assignment functions.
You have to override assignment operator. And the code should be as shown below
#include <iostream>
using namespace std;
class Distance
{
private:
const float MTF;
int feet;
float inches;
public:
Distance() : feet(0), inches(0.0), MTF(3.280833F)
{ }
Distance(float meters) : MTF(3.28033F)
{
float fltfeet = MTF * meters;
feet = int(fltfeet);
inches = 12*(fltfeet-feet);
}
Distance(int ft, float in) : feet(ft), inches(in), MTF(3.280833F)
{ }
void getdist()
{
cout << "\nEnter feet: "; cin >> feet;
cout << "Enter inches: "; cin >> inches;
}
void showdist() const
{ cout << feet << "\'-" << inches << '\"'; }
operator float() const
{
float fracfeet = inches/12;
fracfeet += static_cast<float>(feet);
return fracfeet/MTF;
}
Distance& operator=(const Distance & otherD)
{
feet = otherD.feet;
inches = otherD.inches;
return *this;
}
};
int main()
{
float mtrs;
Distance dist1 = 2.35F;
cout << "\ndist1 = "; dist1.showdist();
mtrs = static_cast<float>(dist1);
cout << "\ndist1 = " << mtrs << " meters\n";
Distance dist2(5, 10.25);
mtrs = dist2;
cout << "\ndist2 = " << mtrs << " meters\n";
Distance dist3; //here is the error
dist3 = (Distance)mtrs ;
//cout<<"\ndist3 = ";dist3.showdist();
return 0;
}
Like another user said, you have a "const" variable, so you have to override assigment operator to address your requirements.
If you want to have class scope constant, you better change your class definition to:
class Distance
{
private:
static constexpr float MTF = 3.280833F;
int feet;
float inches;
public:
Distance() : feet(0), inches(0.0)
...
This will eliminate error you get and will work as you intended. Plus you do not have to define that constant value multiple times as you have in your code.
Note: if you cannot use C++11 you can make MTF global constant (better in unnamed namespace inside cpp file) or just static member. Either way it will eliminate the error and you will need to define it only once, which is less error prone.
I gather that the error comes at the line
dist3 = mtrs;
The problem here is that Distance does not have an assignment operator that takes an argument of type float, so the compiler tries to create a temporary object of type Distance and construct it with the argument mtrs; that's okay, but the next step is to assign that temporary value to dist3, and the compiler is complaining that it can't assign the value of MTF in the temporary object to the value of MTF in dist3 because MTF is const.
Because of that const, objects of type Distance cannot be assigned. So, for example, dist3 = dist2 would also fail. That's probably not what you intended, and you can fix this by adding an assignment operator that simply ignores the value of MTF.
The error occurs, because you could not declare const inside a class. You should define the const variable outside the class. You should replace const float MTF with float MTF here.
As stated in other answers, the issue is that you have declared the MTF variable as const. There are ways around this though. You've set the variable to be const because it's a constant and shouldnt change. Instead, add a dedicated Distance& operator=(float feet) Method in which you actually set the feet and inches variable when passed in a float value:
class Distance
{
private:
/* ... */
public:
/* ... */
Distance& operator=(float feet)
{
// Set the feet and inches here from
// the passed feet variable
return *this;
}
};
That should solve the problem of assigning the variable from a float.
I am very new to programming, and am near the end of this program, but cannot quite finish the last detail, which I have been stuck on. I am attempting to switch what shape pointer *sp is pointing to, and it seems to me that what I am doing should work, since rectangle and circle both are shapes; however, when I compile, only the value of the color changes. The area of the circle prints instead of the area of the rectangle and the perimeter prints 0. Any help would be greatly appreciated!
#include <iostream>
#include <string>
using namespace std;
double const pi = 3.1519;
class shape {
public:
shape() {};
shape(string);
virtual double getCircumference() {
return 0;
};
virtual double getPerimeter() {
return 0;
};
virtual double getArea() {
return 0;
};
string getColor();
protected:
string color;
};
string shape::getColor() {
return color;
}
class circle : public shape {
public:
circle(double r, string c) {
radius = r;
color = c;
};
double getArea();
double getCircumference();
private:
double radius;
};
double circle::getCircumference() {
return pi * radius * 2;
}
double circle::getArea() {
return pi * radius * radius;
}
class rectangle:public shape {
public:
rectangle(double w, double l, string c) {
width = w;
length = l;
color = c;
};
double getArea();
double getPerimeter();
private:
double length;
double width;
};
double rectangle::getPerimeter() {
return width * 2 + length * 2;
}
double rectangle::getArea() {
return length * width;
}
void change(shape *sp, shape *sp1) {
*sp = *sp1;
}
int main() {
circle mary(3.2, "Green");
shape *sp = new circle(4.5, "Yellow");
cout << "Circle #1 is " << mary.getColor() << endl;
cout << "Circle #1 has an area of " << mary.getArea() << endl;
cout << "Circle #1 has a circumference of " << mary.getCircumference() << endl << endl;
cout << "Circle #2 is " << sp->getColor() << endl;
cout << "Circle #2 has an area of " << sp->getArea() << endl;
cout << "Circle #2 has a circumference of " << sp->getCircumference() << endl << endl;
shape *sp1 = new rectangle(1.0, 2.1, "Red");
change(sp, sp1);
cout << "Rectangle #1 is " << sp->getColor() << endl;
cout << "Rectangle #1 has an area of " << sp->getArea() << endl;
cout << "Rectangle #1 has a perimeter of " << sp->getPerimeter() <<endl<< endl;
}
It’s important to keep in mind what is meant by various different ways of using pointers. In your program, sp refers to the pointer itself—that is, a memory location telling the computer where to find an object. The asterisk in *sp is a ‘dereference’ operator; it takes a pointer and gives you the thing that it is pointing to.
With this in mind, your line *sp = *sp1; is saying, ‘take the thing that sp is pointing to, and set it to be equal to the thing that sp1 is pointing to.’ In other words, you are changing the value of the object pointed to by sp, not the value of sp itself. To point sp at the object pointed to by sp1, you need sp = sp1; with no asterisks.
The other thing to bear in mind is that C++ by default passes function arguments by value: when the function is called, the arguments are copied, and the function operates on the copies. This means that the original arguments themselves cannot be changed by a function that works like this. Adding an ampersand to the argument declaration, like void change(shape *&sp, shape *sp1) causes the first argument to be passed by reference: the object operated on by the function is the same object that was passed in by the calling code. This allows the function to change objects passed as arguments, and for those changes to remain after the function has returned.
Sorry for the long answer: I could have given you a few lines that did what you wanted, but I thought you might appreciate an explanation of the reason why things work the way they do.
If you are trying to change the address of pointers, you must pass pointers by reference. Try this:
void change(shape *&sp, shape *&sp1)
A pointer is passed by value even if it's a pointer.
This means that you are actually passing the address by value, so the argument is a copy of the original argument.
Think about
void sum(int a, int b, int result);
void foo() {
int result;
sum(5,10,result);
}
While you expect to be able to store the result into the variable passed to the sum argument you won't be able to do it since result is passed by value and hence copied. Every modification you do to result inside the method will be local to the method.
That's exactly the same thing, a pointer is nothing more than an address, if you pass it by value then a copy of the address is passed but every modification to the local variable is just local.
That's why you must use references if you want to be able to modify their values, exactly as every other variable, so you would have
void sum(int a, int b, int& result);
void change(shape*& shape1, shape*& shape2);
This, under the hood, will pass the address to the variable which stores the address (a sort of shape**) so the function is able to know where the original argument is located and modify it directly.
I'm currently working on my C++ assignment and I'm working through polymorphism and I keep getting error messages. Would appreciate any help. Thanks in advance!
The assignment uses a shape inheritance hierarchy that looks like this:
Circle
Two Dimensional Shape
Cylnder
Shape
Three Dimensional Shape
Below is the error messages I'm getting.
1>Circle.obj : error LNK2019: unresolved external symbol "public: __thiscall TwoDimensionalShapes::TwoDimensionalShapes(void)" (??0TwoDimensionalShapes##QAE#XZ) referenced in function "public: __thiscall Circle::Circle(void)" (??0Circle##QAE#XZ)
1>Cylinder.obj : error LNK2019: unresolved external symbol "public: __thiscall ThreeDimensionalShapes::ThreeDimensionalShapes(void)" (??0ThreeDimensionalShapes##QAE#XZ) referenced in function "public: __thiscall Cylinder::Cylinder(void)" (??0Cylinder##QAE#XZ)
I'm pretty much done with my program but I'm not sure where the problems are coming from.
Here's my source code:
#include "Cylinder.h"
#include "Circle.h"
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
// next line commented out because will now cause compile error
// Shape shpeObj; // instantiate a Shape object
cout << "The Shape object count is: " << Shape::getObjectCount() << '\n';
Circle crclObj; // instantiate a Circle object
Cylinder cyldObj; // instantiate a Cylinder object
// Count will be 2 in statement below because a Shape object is contained
// within each Circle and Cylinder object.
cout << "The Shape object count is: " << Shape::getObjectCount() << "\n";
Shape * shpePtr = &cyldObj; // declare a Shape pointer
// and have it point to the Cylinder object
Shape & shpeRef = cyldObj; // declare a Shape reference
// and have it reference the Cylinder object
// The above 2 statments are ok because a derived class object IsA base class object!
// No additional objects created, so the count is still the same.
cout << "The Shape object count is: " << Shape::getObjectCount() << "\n";
// Dynamically create 2 objects
Shape * shpePtr2 = new Circle;
Shape & shpeRef2 = *new Cylinder;
// The count should now be 4
cout << "The Shape object count is: " << Shape::getObjectCount() << "\n";
// Now destroy the 2 dynamically created objects!
delete shpePtr2;
delete &shpeRef2;
//The count should now be 2 again.
cout << "The Shape object count is: " << Shape::getObjectCount() << "\n\n";
/* Can no longer test Shape class, since it is now an Abstract Base Class (ABC)
// Test Shape class
shpeObj.setNoOfSides(0);
cout << "The number of sides is: " << shpeObj.getNoOfSides() << "\n\n";
cout << "The area of shpeObj is: " << shpeObj.Area() << '\n';
cout << "The volume of shpeObj is: " << shpeObj.Volume() << "\n\n\n";
*/
// Test Circle class
crclObj.setRadius(3.0);
cout << fixed << setprecision(4); // force use of decimal point and 4 digits of
// precision after the decimal place
cout << "The radius of crclObj is: " << crclObj.getRadius() << "\n\n";
cout << "The number of sides is: " << crclObj.getNoOfSides() << "\n\n";
cout << "The area of crclObj is: " << crclObj.Area() << '\n';
// next line no longer valid in my solution for this assignment
//cout << "The volume of crclObj is: " << crclObj.Volume() << "\n\n\n";
// Test Cylinder class
cyldObj.setRadius(5.5);
cyldObj.setHeight(2.5);
cout << "The radius of cyldObj is: " << cyldObj.getRadius() << '\n';
cout << "The height of cyldObj is: " << cyldObj.getHeight() << "\n\n";
cout << "The number of sides is: " << cyldObj.getNoOfSides() << "\n\n";
cout << "The area of cyldObj is: " << cyldObj.Area() << '\n';
cout << "The volume of cyldObj is: " << cyldObj.Volume() << "\n\n";
return 0;
}
#pragma once
class Shape
{
public:
Shape(void); //constructor
~Shape(void); //destructor
void setNoOfSides(const int &); // set the # of sides
int getNoOfSides() const; // get the # of sides
static int getObjectCount(); // get the object count
virtual double Area() const = 0; // calculate and return area
// now a pure virtual function
virtual double Volume() const; // calculate and return volume
protected:
int mNoOfSides; // represents # of sides in Shape object
static int mObjectCount; // a static member - counts the # of Shape
// objects currently instantiated
// Only one of these instantiated for the whole class!
};
#pragma once
#include "Shape.h"
class TwoDimensionalShapes :public Shape
{
public:
TwoDimensionalShapes(void); //constructor
virtual double Area() const = 0; // area of 2D shape
};
#pragma once
#include "Shape.h"
class ThreeDimensionalShapes :public Shape
{
public:
ThreeDimensionalShapes(void); // constructor
virtual double Area() const = 0; // area of 3D shape
virtual double Volume() const = 0; // volume of 3D shape
};
#pragma once
#include "TwoDimensionalShapes.h"
class Circle :public TwoDimensionalShapes
{
public:
Circle(void); // constructor
void setRadius(const double &); //set the radius
double getRadius() const; // get the radius
virtual double Area() const override; // overrides Area() method of TwoDimensionalShapes class
protected:
const static double pi; // Static member used in calculations
// Only one of these instantiated for the whole class!
double mRadius; // member used to represent radius
};
#pragma once
#include "ThreeDimensionalShapes.h"
class Cylinder :public ThreeDimensionalShapes
{
public:
Cylinder(void); // constructor
void setHeight(const double &); // set the height
double getHeight() const; // get the height
void setRadius(const double &); //set the radius
double getRadius() const; // get the radius
virtual double Area() const override; // overrides Area() method of ThreeDimensionalShapes class
virtual double Volume() const override; // overrides Volume() method of ThreeDimensionalShapes class
protected:
const static double pi; // Static member used in calculations
// Only one of these instantiated for the whole class!
double mHeight; // member used to represent height
double mRadius;
};
#include "Circle.h"
// init static data member
const double Circle::pi = 3.141592654; // init. static member
// constructor
Circle::Circle(void)
:mRadius(0.0)
{
setNoOfSides(0);
}
// used to set value for mRadius member
void Circle::setRadius(const double & setVal)
{
if (setVal > 0.0) // Make sure input is a valid value
{
this->mRadius = setVal;
}
// otherwise just leave set to original value
}
// used to return current value of mRadius member
double Circle::getRadius(void) const
{
return this->mRadius;
}
// used top calculate and return area.
double Circle::Area(void) const
{
return Circle::pi * this->mRadius * this->mRadius;
}
#include "Cylinder.h"
// init static data member
const double Cylinder::pi = 3.141592654; // init. static member
// constructor
Cylinder::Cylinder(void)
:mHeight(0.0)
{
this->setNoOfSides(3); // Why not init. this member in MIL ???
}
// used to set mHeight member
void Cylinder::setHeight(const double & setVal)
{
if (setVal > 0.0) // Make sure input is a valid value
{
this->mHeight = setVal;
}
// otherwise just leave set to original value
}
// used to return current value of mHeight member
double Cylinder::getHeight(void) const
{
return this->mHeight;
}
// used to set value for mRadius member
void Cylinder::setRadius(const double & setVal)
{
if (setVal > 0.0) // Make sure input is a valid value
{
this->mRadius = setVal;
}
// otherwise just leave set to original value
}
// used to return current value of mRadius member
double Cylinder::getRadius(void) const
{
return this->mRadius;
}
// used to caluclate and return area
double Cylinder::Area(void) const
{
double TwoPiR = 2.0 * Cylinder::pi * this->mRadius;
return (TwoPiR * this->mRadius) + (TwoPiR * this->mHeight);
}
// used to claculate and return volume
double Cylinder::Volume(void) const
{
return Cylinder::pi * this->mRadius * this->mRadius * this->mHeight;
}
#include "Shape.h"
// init static data memeber
int Shape::mObjectCount = 0;
// constructor
Shape::Shape(void)
:mNoOfSides(1)
{
++Shape::mObjectCount;
}
// desstructor
Shape::~Shape(void)
{
--Shape::mObjectCount;
}
// used to set mNoOfSides member
void Shape::setNoOfSides(const int & setVal)
{
if (setVal > 0)
{
this->mNoOfSides = setVal;
}
// otherwise just leave set to original value
}
// used to return current value of mNoOfSides member
int Shape::getNoOfSides() const
{
return this->mNoOfSides;
}
// used to return current value of mObjectCount static member
int Shape::getObjectCount()
{
return Shape::mObjectCount;
}
/* no longer required to be implemented now that it is a
pure virtual function
// used to calculate and return area
double Shape::Area(void) const
{
return 0.0;
}
*/
// used to calculate and return volume
double Shape::Volume(void) const
{
return 0.0;
}
OK I figured it out now. I forgot to provide a constructor implementation for my TwoDimensionalShapes and ThreeDimensionalShapes classes. Silly mistake.