Reputation: 19
This program contains three parts: the header, the functions for the class and the main part that is interactive. However, it won't compile.
I keep getting the response that there is an expected constructor, destructor or type conversion.
#ifndef BOX_H
#define BOX_H
class Box
{
private:
double height;
double width;
double length;
public:
Box();
double setHeight();
double setWidth();
double setLength();
double getVolume();
double getSurfaceArea();
};
#endif
function.cpp
:
#include "Box.hpp"
/**********************************************************************
Box:: Box
This is the default constructor that uses the set methods to initialize each field to 1.
* **********************************************************************/
Box::Box()
{
height = 1;
width = 1;
length = 1;
}
/*
Does anyone know what this section does? Is it another default constructor or is is it even needed?
Box::Box(double height, double width, double length)
{
setHeight(height);
setWidth(width);
setLength(length);
}
*/
double Box::setHeight()
{
return height;
}
double Box::setWidth()
{
return width;
}
double Box::setLength()
{
return length;
}
double Box::getVolume()
{
return height * width * length;
}
double Box::getSurfaceArea()
{
double SurAre = 0;
SurAre = (2 * (length * width)) + (2 * (length * height)) + (2 * (height * width));
return SurAre;
}
main.cpp
:
#include <iostream>
#include "Box.hpp" //contains Box class declaration
using namespace std;
int main()
{
Box object;
double Alength;
double Awidth;
double Aheight;
cout << "This program will calculate the area of a box.\n";
cout << "What is the length?";
cin >> Alength;
cout << "What is the width?";
cin >> Awidth;
cout << "What is the height?";
cin >> Aheight;
object.setLength(Alength);
if (!object.setWidth(Awidth))
cout << "Invalid box width entered. \n" << endl;
if (!object.setHeight(Aheight))
cout << "Invalid box height entered. \n" << endl;
cout << "Volume: " << object.getVolume() << endl;
cout << "Surface Area: " << object.getSurfaceArea() << endl;
return 0;
}
Does anyone have an idea about why?
Upvotes: 1
Views: 597
Reputation: 572
You have a problem with your class declaration/definition: Your setters should have parameters so you can use them as setters. In your Box.hpp change
double setHeight();
double setWidth();
double setLength();
to
double setHeight(double _height);
double setWidth(double _width);
double setLength(double _length);
Then in your Box.cpp change
double Box::setHeight()
{
return height;
}
double Box::setWidth()
{
return width;
}
double Box::setLength()
{
return length;
}
to
double Box::setHeight(double _height)
{
height = _height;
return height;
}
double Box::setWidth(double _width)
{
width = _width;
return width;
}
double Box::setLength(double _length)
{
length = _length;
return length;
}
Upvotes: 0
Reputation: 10564
C++ has some strange behaviors: if you fail to declare and define a default constructor, it will do it for you. Think autogenerated. It will also define a compiler-generated copy constructor and destructor. It's helpful to understand this, because these things exist whether you define them or not.
You both declared the constructor in the header:
public:
Box();
and defined it in the cpp file:
Box::Box()
You correctly both declared and defined this constructor.
If you want any other constructor, you have to declare it before you can define it as well
public:
Box();
Box(double height, double width, double length); // this is new
and then you can uncomment your definition in the cpp file, and all should be well.
One other style point: the way you've defined your 3 parameter constructor is not great style. What happens is that you construct a Box, and when you do so, you use the default constructor for it's member variables of height, width, and depth. You then call 3 member functions to assign these variables. In C++ you can avoid all this by using an initializer list. The body of your 3 parameter constructor becomes
Box::Box(double height, double width, double length) :
height(height), width(width), length(length)
{}
What this says is "build me a Box, and as you do so, use the value of passed in height for member height, width for member width, length for member length". You save yourself an assignment of 0 as a default value for the member variables and 3 function calls by building your Box "out of the box" as it were with those values. This uses the copy constructor for your member variables rather than their default constructors followed by an assignment.
(technical note: as builtins, doubles technically don't have these constructors, but the semantics behave as if they do, so you can think of them as having them on first order thought.)
This means, additionally, that if you define a copy constructor:
Box(const Box& other);
then you can use that in other classes to initialize a Box in their initializer lists, e.g.
BunchOfBoxes(const Box& firstBox) :
m_firstBox(firstBox)
{}
and it will use your copy constructor from the Box class to do the same sort of initialize-on-build for BunchOfBoxes
Upvotes: 1
Reputation: 283684
If you uncomment the three-parameter constructor, you will get an error message, because a constructor is a class member, and class members have to be declared inside the class before they can be used or defined outside.
Add the line
Box(double height, double width, double length);
inside your class definition, and then the additional constructor can be compiled also.
Upvotes: 1