I've been working on a program that calculates the volume of a box, using classes to help me understand how to use classes. As part of the program I want to convert my objects length,width and height into a string to display the dimensions of the box. When I run the code from my main file it crashes. When I run it from the class file I get "could not convert Box::length from double to std::string. How can I fix the conversion error?
#include <iostream>
#include <stdexcept>
#include <sstream>
#include <iomanip>
#include <string>
using namespace std;
class Box
{
public:
double length;//length of the box
double height;//height of the box
double width;//with of the box
Box(): length(1), height(1), width(1){}
//Parameterized Constructor
Box(double length, double width, double height);
double getVolume(void);
//Mutators
void setLength(double leng);
void setWidth(double wid);
void setHeight(double hei);
//Acessors
string toString() const;
string getLength();
string getWidth();
string getHeight();
};//end class
//member function definitions
double Box::getVolume(void)//get volume will cal and output the volume when called
{
return length * width * height;
}
void Box::setLength(double leng)
{
const double MIN_LENGTH = 0.1;//constants for min/max for range check and out_of_range exception
const double MAX_LENGTH = 99;
if (length > MAX_LENGTH || length < MIN_LENGTH)
{
stringstream strOut;//declare string stream
strOut << "Length is out of range. Length must be between" << MIN_LENGTH << " and " << MAX_LENGTH << ".";//error msg
throw out_of_range(strOut.str());
}
else
{
length = leng;// if length is within range, store it
}
}
string Box::getLength()
{
return length;
}
void Box::setWidth(double wid)
{
const double MIN_WIDTH = 0.1;//constants for min/max for range check and out_of_range exception
const double MAX_WIDTH = 99;
if (length > MAX_WIDTH || length < MIN_WIDTH)
{
stringstream strOut;//declare string stream
strOut << "Width is out of range. Width must be between" << MIN_WIDTH << " and " << MAX_WIDTH << ".";//error msg
throw out_of_range(strOut.str());
}
else
{
width = wid;// width is in range, store it
}
}
string Box::getWidth()
{
return width;
}
void Box::setHeight(double hei)
{
const double MIN_HEIGHT = 0.1;//constants for min/max for range check and out_of_range exception
const double MAX_HEIGHT = 99;
if (length > MAX_HEIGHT || length < MIN_HEIGHT)
{
stringstream strOut;//declare string stream
strOut << "Height is out of range. Height must be between" << MIN_HEIGHT << " and " << MAX_HEIGHT << ".";//error msg
throw out_of_range(strOut.str());
}
else
{
height = hei;// height is in range, store it
}
}
string Box::getHeight()
{
return height;
}
string Box::toString() const
{
stringstream strOut;
strOut << "Length: " << getLength() << endl
<< "Width: " << getWidth() << endl <<
"Height: " << getHeight() << endl;
return strOut;
}
This compile error is occurring at the return statements of your getWidth, getHeight, getLength functions. This is because the you declared them to return a string but instead returned a width, height, and length which are doubles. The compiler sees that there is no automatic conversion from double to string.
To fix this you only need to fix the return type of the function from string to double:
double getLength();
double getWidth();
double getHeight();
I noticed one more error:
doubletostring.cpp:104:25: error: reference to non-static member function must be called
strOut << "Length: " << getLength << endl
And similar errors in the toString method. Simply convert them to function calls by adding () at the end:
strOut << "Length: " << getLength() << endl
Your class definition says getLength() will return a string, however your getLength() function actually returns width, which is a double. You probably meant to convert length to a string before you return it.
You could use the to_string() function in the string library, and change your getLength() to
return to_string(length)
Related
My program is supposed to print a "to" and "from" address sourced from the EndPoint toString method but I can't quite figure out how to implement it. Here is my code. How do I get the toString method in the Package::Package constructor to print the contents of the EndPoint's toString method?
// ShippingProgram.cpp :
//
#include "stdafx.h"
#include <iomanip>
#include <stdexcept>
#include <sstream>
#include <iostream>
#include "Package.h" // Package class definition
using namespace std;
// constructor
EndPoint::EndPoint(const string& nameInfo, const string& addressInfo, const string& cityInfo, const string& stateInfo, int zipInfo) {
name = nameInfo;
address = addressInfo;
city = cityInfo;
state = stateInfo;
zip = zipInfo;
}
string EndPoint::toString() const {
ostringstream output;
output << fixed << setprecision(2); // two digits of precision
output << name << "\n" << address << "\n" <<
city << ", " << state << " " << zip;
return output.str();
}
Package::Package(EndPoint senderInfo, EndPoint receiverInfo, double weightInfo, double costPerOzInfo) {
weight = weightInfo; // should validate
costPerOz = costPerOzInfo;
}
void Package::calculateCost(double)
{
}
double Package::calculateCost() const {
return weight * costPerOz;
}
string Package::toString() const {
ostringstream output;
output << fixed << setprecision(2); // two digits of precision
output << "\nFrom:\n" << senderInfo.toString() << "\n\nTo:\n" << receiver <<
"\n\nWeight: " << weight << endl <<
"\nShipping cost:\n" << calculateCost();
return output.str();
}
Main Method:
#include <iostream>
#include <iomanip>
#include "stdafx.h"
//#include "TwoDayPackage.h"
//#include "OvernightPackage.h"
#include "Package.h"
using namespace std;
int main()
{
// Three address records.
EndPoint homer{ "Homer Simpson", "742 Evergreen Terrace", "Springfield",
"FL", 32401 };
EndPoint donald{ "Donald Duck", "1313 Webfoot Walk", "Duckburg",
"CA", 95501};
EndPoint kermit{ "Kermit Frog", "On the Swamp", "Leland", "MS", 38756 };
// This calls the base class constructor (regular fee).
Package regular{ homer, donald, 25.0, 0.20 };
// Defines output precision for floating point numbers (iomanip).
// cout << fixed << setprecision(2);
// Prints package parameters.
cout << "Regular package processed." << endl;
cout << regular.toString();
cout << "Shipping Cost: $" << regular.calculateCost() << endl << endl;
cout << homer.toString();
// First derived class (two-day fee added).
/* TwoDayPackage twoday{ donald, kermit, 17.5, 0.20, 2.0 };
cout << "Two-day package processed." << endl;
cout << twoday.toString();
cout << "Shipping Cost: $" << twoday.calculateCost() << endl << endl;
// Second derived class (overnight fee added).
OvernightPackage overnight{ kermit, homer, 14.2, 0.20, 0.50 };
cout << "Overnight package processed." << endl;
cout << overnight.toString();
cout << "Shipping Cost: $" << overnight.calculateCost() << endl << endl;
*/
}
This project requires that I create a shipping program with inheritance. It must include a "EndPoint" class that is private and contains the sender and receiver info and a "Package" class that compiles everything and puts it to string.
My Errors are with how in the world I get my Package constructor to be able to contain the information from my EndPoint class. Since the main method is formatted where the Package class must be (EndPoint, EndPoint, Weight, Cost) but it doesn't compile like that. I guess I just don't understand how to send the EndPoint info to the Package objects.
Here are my errors:
No instance of constructor "Package::Package" matches the argument list argument types are: (EndPoint, EndPoint, double, double)
Error C2440 'initializing': cannot convert from 'initializer list' to 'Package'
Error C3861 'setprecision': identifier not found
Package.h
#pragma once
#ifndef PACKAGE_H
#define PACKAGE_H
#include <string>
#include <iostream>
using namespace std;
class EndPoint {
public:
EndPoint(const std::string&, const std::string&, const std::string&, const std::string&, int = 0.0);
void setName(const std::string&);
std::string getName() const;
void setAddress(const std::string&);
std::string getAddresss() const;
void setCity(const std::string&);
std::string getCity() const;
void setState(const std::string&);
std::string getState() const;
void setZip(int);
int getZip() const;
string toString() const;
protected:
std::string name;
std::string address;
std::string city;
std::string state;
int zip;
};
class Package {
public:
string toString() const;
Package(const std::string&, const std::string&, double = 0.0, double = 0.0);
void setSender(const std::string&);
std::string getSender() const;
void setReceiver(const std::string&);
std::string getReceiver() const;
void setWeight(double);
double getWeight() const;
void setCostPerOz(double);
double getCostPerOz() const;
void calculateCost(double);
double calculateCost() const;
double calculateCost(double weight, double costPerOz)
{
double shipping;
shipping = weight * costPerOz;
cout << "The Base Cost = " << shipping << endl << endl;
return shipping;
}
protected:
std::string sender;
std::string receiver;
double weight; // gross weekly sales
double costPerOz; // commission percentage
};
#endif
Package.cpp
#include "stdafx.h"
#include <iomanip>
#include <stdexcept>
#include <sstream>
#include "Package.h" // Package class definition
using namespace std;
// constructor
EndPoint::EndPoint(const string& nameInfo, const string& addressInfo, const string& cityInfo, const string& stateInfo, int zipInfo) {
name = nameInfo;
address = addressInfo;
city = cityInfo;
state = stateInfo;
zip = zipInfo;
}
void EndPoint::setName(const string& nameInfo) {
name = nameInfo;
}
string EndPoint::getName() const { return name; }
void EndPoint::setAddress(const string& addressInfo) {
address = addressInfo;
}
string EndPoint::getAddresss() const { return address; }
void EndPoint::setCity(const string& cityInfo) {
city = cityInfo;
}
string EndPoint::getCity() const { return city; }
void EndPoint::setState(const string& stateInfo) {
state = stateInfo;
}
string EndPoint::getState() const { return state; }
void EndPoint::setZip(int zipInfo) {
zip = zipInfo;
}
int EndPoint::getZip() const {
return zip;
}
string EndPoint::toString() const {
ostringstream output;
output << fixed << setprecision(2); // two digits of precision
output << name << "\n" << address << "\n" <<
city << ", " << state << " " << zip;
return output.str();
}
string EndPoint::getState() const { return state; }
Package::Package(const string& senderInfo, const string& receiverInfo, double weightInfo, double costPerOzInfo) {
sender = senderInfo; // should validate
receiver = receiverInfo; // should validate
weight = weightInfo; // should validate
costPerOz = costPerOzInfo;
}
void Package::setSender(const string& senderInfo) {
sender = senderInfo; // should validate
}
string Package::getSender() const { return sender; }
void Package::setReceiver(const string& receiverInfo) {
receiver = receiverInfo; // should validate
}
string Package::getReceiver() const { return receiver; }
void Package::setWeight(double weightInfo) {
if (weightInfo < 0.0) {
throw invalid_argument("The package weight must be >= 0.0");
}
weight = weightInfo;
}
double Package::getWeight() const { return weight; }
void Package::setCostPerOz(double costPerOzInfo) {
costPerOz = costPerOzInfo;
}
double Package::getCostPerOz() const {
return costPerOz;
}
double Package::calculateCost() const {
return weight * costPerOz;
}
string Package::toString() const {
ostringstream output;
output << fixed << setprecision(2); // two digits of precision
output << "From:\n" << sender << "\n\nTo:\n" << receiver <<
"\n\nWeight: " << weight << endl <<
"\nShipping cost: " << calculateCost();
return output.str();
}
Main.cpp
#include <iostream>
#include <iomanip>
#include "stdafx.h"
//#include "TwoDayPackage.h"
//#include "OvernightPackage.h"
#include "Package.h"
using namespace std;
int main()
{
// Three address records.
EndPoint homer{ "Homer Simpson", "742 Evergreen Terrace", "Springfield",
"FL", 32401 };
EndPoint donald{ "Donald Duck", "1313 Webfoot Walk", "Duckburg",
"CA", 95501};
EndPoint kermit{ "Kermit Frog", "On the Swamp", "Leland", "MS", 38756 };
// This calls the base class constructor (regular fee).
Package regular{ homer, donald, 25.0, 0.20 };
// Defines output precision for floating point numbers (iomanip).
cout << fixed << setprecision(2);
// Prints package parameters.
cout << "Regular package processed." << endl;
cout << regular.toString();
cout << "Shipping Cost: $" << regular.calculateCost() << endl << endl;
// First derived class (two-day fee added).
/* TwoDayPackage twoday{ donald, kermit, 17.5, 0.20, 2.0 };
cout << "Two-day package processed." << endl;
cout << twoday.toString();
cout << "Shipping Cost: $" << twoday.calculateCost() << endl << endl;
// Second derived class (overnight fee added).
OvernightPackage overnight{ kermit, homer, 14.2, 0.20, 0.50 };
cout << "Overnight package processed." << endl;
cout << overnight.toString();
cout << "Shipping Cost: $" << overnight.calculateCost() << endl << endl;
*/
}
I have commented out blocks of code here as I am trying to just get the first part to work before diving into the rest.
Edit:
Thank you all for the advice! I have made some edits and taken out a ton of extra code (getters and setter. I learned with java...) and I have gotten the program to compile and work as intended save for a small but important issue.
No instance of constructor "Package::Package" matches the argument
list argument types are: (EndPoint, EndPoint, double, double)
in your code:
Package regular{ homer, donald, 25.0, 0.20 }; you are passing wrong variables to the constructor's parameters which is an Endpoint object for first and second parameter
what you have is:
Package(const std::string&, const std::string&, double = 0.0, double = 0.0);
which accepts a std::string object for first and second parameter.
cannot convert from 'initializer list' to 'Package
fixing problem 1 will fix this
i dont know why you get 3rd one since you have iomanip in your main
I am trying to print with a function from a function in a derived class with a function from the base class within it and I am not exactly sure if I should be
how I can print out both information from the Shape toString function and the Rectangle toString function.
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
class Shape
{
public:
Shape(double w, double h);
string toString();
private:
double width;
double height;
};
Shape::Shape(double w, double h)
{
width = w;
height = h;
}
string Shape::toString()
{
stringstream ss;
ss << "Width: " << width << endl;
ss << "Height: " << height << endl;
return ss.str();
}
class Rectangle : public Shape
{
public:
Rectangle(double w, double h, int s);
string toString();
private:
int sides;
};
string Rectangle::toString()
{
//
// Implement the Rectangle toString function
// using the Shape toString function
Shape::toString();
cout << toString();
stringstream ss;
ss << "Sides: " << sides << endl;
return ss.str();
}
// Use the constructor you created
// for the previous problem here
Rectangle::Rectangle(double w, double h, int s)
:Shape(w, h)
{
sides = s;
}
The only parts that can be manipulated in the problem are the sections that come after the comments
I think the problem is with this line:
cout << toString();
since it is going to recursively call itself and eventually you will run out of stack and get the runtime error.
your implementation should be:
string Rectangle::toString()
{
// Implement the Rectangle toString function
// using the Shape toString function
stringstream ss;
ss << Shape::toString();
ss << "Sides: " << sides << endl;
return ss.str();
}
Also consider making this method const and virtual in the case you want polymorphism to work properly.
This Complex Number program is supposed to take three arguments from a txt document, the first to indicate whether the subsequent two are numbers in polar or rectangular form, and output every complex number given in both rectangular and polar form. Both the header file and source code are shown here. The txt document is in the following format:
p 50 1.2
r 4 0.8
r 2 3.1
p 46 2.9
p 3 5.6
Without declaring the int inputfile() function as static within the class declarations, the build gives an error 'illegal call of non-static member function'.
With the static declaration of the function (shown below), the build gives errors referring to the class members Pfirst, Psecond, Rfirst and Rsecond inside function definition inputfile(), being 'illegal references to non-static members'.
The member declarations cannot then be made static as well because the class would not be able to initialise the parameters within the constructor.
How can I bypass this 'static' problem?
#define Complex_h
class Complex
{
char indicator;
const double pi;
public:
double Pfirst, Psecond, Rfirst, Rsecond;
Complex(char i = 0, double Pf = 0, double Ps = 0, double Rf = 0, double Rs = 0, const double pi = 3.14159265) // with default arguments (= 0)
: indicator(i), Pfirst(Pf), Psecond(Ps), Rfirst(Rf), Rsecond(Rs), pi(pi) {}
~Complex();
void poltorect();
void recttopol();
static int inputfile();
};
#include <iostream>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <string>
#include "Complex.h"
using namespace std;
int Complex::inputfile()
{
ifstream ComplexFile;
ComplexFile.open("PolarAndRectangular.txt");
string TextArray[3];
string TextLine;
stringstream streamline, streamfirst, streamsecond;
while (getline(ComplexFile,TextLine))
{
streamline << TextLine;
for (int j=0; j<3; j++)
{streamline >> TextArray[j];}
streamline.str("");
streamline.clear();
if (TextArray[0] == "r")
{
streamfirst << TextArray[1];
streamfirst >> Rfirst;
streamsecond << TextArray[2];
streamsecond >> Rsecond;
cout << "Complex number in rectangular form is " << Rfirst << "," << Rsecond << endl;
void recttopol();
cout << "Complex number in polar form is " << Pfirst << "," << Psecond << endl;
}
else
{
streamfirst << TextArray[1];
streamfirst >> Pfirst;
streamsecond << TextArray[2];
streamsecond >> Psecond;
cout << "Complex number in polar form is " << Pfirst << "," << Psecond << endl;
void poltorect();
cout << "Complex number in rectangular form is" << Rfirst << "," << Rsecond << endl;
}
streamfirst.str("");
streamfirst.clear();
streamsecond.str("");
streamsecond.clear();
}
ComplexFile.close();
system("pause");
return 0;
}
void Complex::recttopol()
{
Pfirst = sqrt((Rfirst*Rfirst)+(Rsecond*Rsecond));
Psecond = (atan(Rsecond/Rfirst))*(pi/180);
}
void Complex::poltorect()
{
Rfirst = Pfirst*(cos(Psecond));
Rsecond = Pfirst*(sin(Psecond));
}
int main()
{
Complex::inputfile();
system("pause");
return 0;
}
You forgot to create an object of type Complex.
Make your inputfile() method nonstatic and do:
int main()
{
Complex complex; // Object construction.
complex.inputfile();
system("pause");
return 0;
}
I wrote this code and having trouble with passing a three argument constructor that set the first to room number, second to room capacity, Here is where I'm stuck the three part is to set the room rate, and that sets the room occupancy to 0 here is the code that I wrote
#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
class HotelRoom
{
private:
string room_no;
int Capacity;
int occupancy;
double rate;
public:
HotelRoom();
HotelRoom(string, int, int, double );
};
HotelRoom::HotelRoom (string room, int cap, int occup = 0, double rt )
{
room_no = room;
Capacity = cap;
occupancy = occup;
rate = rt;
cout << " Room number is " << room_no << endl;
cout << " Room Capacity is " << Capacity << endl;
cout << " Room rate is " << rate << endl;
cout << "Occupancy is " << occup << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
cout << setprecision(2)
<< setiosflags(ios::fixed)
<< setiosflags(ios::showpoint);
HotelRoom Guest (" 123", 4, 55.13);
system("pause");
return 0;
}
HotelRoom::HotelRoom (string room, int cap, int occup = 0, double rt )
is illegal, if you provide default values they must either
Have no arguments afterwards
all arguments following must also have a default value
To work around this make your occup the last variable in your consructor.
HotelRoom::HotelRoom (string room, int cap, double rt, int occup=0 )
Another note:
Only provide the default value in your header, rewriting the default value will give you an error during declaration.
header.h
HotelRoom(string,int,double,int occup=0);
imp.cpp
HotelRoom::HotelRoom (string room, int cap, double rt, int occup )
{
//...
}
In addition to Gmercer015's answer. In C++11 you can use delegating constructors.
HotelRoom::HotelRoom (string room, int cap, int occup, double rt )
{
...
}
HotelRoom::HotelRoom (string room, int cap, double rt )
: HotelRoom(room, cap, 0, rt)
{}
AFAIR, parameters with default values cannot be followed by parameters without. In your case you should have rate precede occupancy of the latter can have a default value while the former cannot.
I am creating a vector that contains pointers to a base class. In this vector I'm dynamically storing pointers to derived classes which contain some member variables, one of them being a string variable name.
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <string>
#include <cstdlib>
bool hasDirection = false;
bool hasDiameter = false;
int direction;
float diameter;
int starDimension = 0;
int animalDimension = 0;
int fishDimension = 0;
class MovingObject
{
protected:
std::string name;
int direction;
float diameter;
int dimension;
float movingSpeed;
public:
std::string getName(){ return name;};
int getDirection(){ return direction;};
float getDiameter(){ return diameter;};
float getMovingSpeed(){ return movingSpeed;};
int getDimension(){ return dimension;};
void setName(std::string v){ name = v;};
void setDirection(int d){ direction = d;};
void setDiameter(float f){ diameter = f;};
void setMovingSpeed(float s){ movingSpeed = s;};
void setDimension (int d){ dimension = d;};
virtual void PrintContents()=0;
};
static std::vector<MovingObject*> data;
class starObject : public MovingObject
{
public:
void PrintContents()
{
std::cout << "(" << getName() << "," << getDiameter() << "," << getDirection() << ")";
}
};
class animalObject : public MovingObject
{
public:
void PrintContents()
{
std::cout << "(" << getName() << "," << getDiameter() << "," << getDirection() << ")";
}
};
class fishObject : public MovingObject
{
public:
void PrintContents()
{
std::cout << "(" << getName() << "," << getDiameter() << "," << getDirection() << ", [" << getDimension() << "], " << getMovingSpeed() << ")";
}
};
I later set all these member variables inside a main function. The problem is when I try to output the contents of the member variables, all of them show up except for the string name.
Now, I've checked to make sure that the string gets set before calling the PrintContent() method, and it shows that the value is in the vector. However, when I debug through the code, the value is no longer there, instead containing an empty string.
Could someone with better c++ knowledge explain to me why this is happening? This is the main class:
int main()
{
std::string type;
Reader reader;
while (!std::cin.eof())
{
try
{
std::string type;
std::cin >> type;
if (type =="int")
{
reader.ReadDirection();
}
else if (type =="float")
{
reader.ReadDiameter();
}
else if (type == "string")
{
std::string name;
std::cin >> name;
if (hasDirection && hasDiameter)
{
int dimension;
if (diameter > 0 && diameter < 10)
{
//fish
fishObject fish;
fish.setName(name);
fish.setDiameter(diameter);
fish.setDirection(direction);
dimension = fishDimension;
fishDimension += 50;
fish.setDimension(dimension);
fish.setMovingSpeed(0.1);
data.push_back(&fish);
}
else if (diameter >= 10 < 500)
{
//animal
animalObject animal;
animal.setName(name);
animal.setDiameter(diameter);
animal.setDirection(direction);
dimension = animalDimension;
animalDimension += 800;
animal.setDimension(dimension);
animal.setMovingSpeed(5.0);
data.push_back(&animal);
}
else if (diameter >=500)
{
//star
starObject star;
star.setName(name);
star.setDiameter(diameter);
star.setDirection(direction);
dimension = starDimension;
starDimension += 5000;
star.setDimension(dimension);
star.setMovingSpeed(30.0);
data.push_back(&star);
}
}
else
{
throw (IncompleteData(name));
}
}
}
catch (IncompleteData e)
{
std::cerr << "No diameter or direction given for object " << e.objectName << "\n";
}
}
The objects you push to the data vector are local because they are declared inside if/else blocks (see the declarations of fish and animal).
When you push the address of such an object to the vector, it will continue to point to the local object, which ceases to exist at the end of the local scope. You need to create objects that live beyond the local scope. One way of doing this is to create copies of the local objects on the heap and push those to the vector:
data.push_back(new fishObject(fish));
Of course this means that you get a memory leak unless you make sure you explicitly delete the elements of the vector some time before the end of the program. The usual recommendation to avoid having to think of this is to use a vector of std::unique_ptr<MovingObject> instead of a vector of naked pointers.