I am writing a class for college and I have a problem with constructors..
I have to create a class to calculate P and V of a cylinder. I need functions set(), to set the values, get H, get R to get values and P and V to calculate the P and V. I also need 3 constructors, first one to ask the user to enter the values for R and H, second one to set them to 10 and 5.5 and third one to initialize them to 3 and 1.
#include <iostream>
using namespace std;
class Cilindar{
public:
Cilindar();
Cilindar(float R, float H);
float getH();
float getR();
void set();
float Plostina(float R, float H);
float Volumen(float R, float H);
private:
float radius;
float visina;
};
void Cilindar::set(){
cout << "Vnesi go radiusot" << endl;
cin >> radius;
cout << "Vnesi ja visinata" << endl;
cin >> visina;
}
float Cilindar::getH(){
return visina;
}
float Cilindar::getR(){
return radius;
}
float Cilindar::Plostina(float R, float H){
return 2 * R * 3.14 * (R + H);
}
float Cilindar::Volumen(float R, float H){
return R * R * 3.14 * H;
}
Cilindar::Cilindar(){
set();
cout << "Plostinata iznesuva: " << Plostina(radius, visina) << endl;
cout << "Volumenot iznesuva: " << Volumen(radius, visina) << endl;
}
Cilindar::Cilindar(float R, float H){
cout << "Plostinata iznesuva: " << Plostina(R, H) << endl;
cout << "Volumenot iznesuva: " << Volumen(R, H) << endl;
}
int main()
{
Cilindar c1, c2(10, 5.5), c3;
return 0;
}
This is what I have so far, I made the first constructor to ask the user, second one with 10 and 5.5 but third one I don't know how can I initialize the values to the constructor, because a constructor with 2 arguments already exists, so what is another way to do it?
Thank you.
Just call the constructor with 2 arguments again (with different parameters).
Cilindar c1, c2(10, 5.5), c3(3, 1);
There is no need for another constructor.
Good luck.
Related
I am trying to write a wind chill calculator that works with temp. and wind speed values from user input. I have never used the pow() function before and I'm not sure if I am using it properly. My code is this:
#include <iostream>
#include <cmath>
using namespace std;
float windChillCalculator(float T, float V)
{
float wind_chill;
wind_chill = (35.74 + (0.6215 * T) - (35.75 * (pow(V, 0.16)))
+ ((0.4275 * T) * (pow(V, 0.16))));
return wind_chill;
}
int main()
{
float T;
float V;
cout << "Enter temperature (F): " << endl;
cin >> T;
cout << "Enter wind speed (mph): " << endl;
cin >> V;
float wind_chill;
windChillCalculator(T, V);
cout << endl << "Wind chill is " << wind_chill << endl;
}
Regardless of input it returns 4.59e-41. Please help me figure out why..
Thanks.
The problem here is probably that you are using two variables, both named wind_chill. First definition of wind_chill is in windChillCalculator function. This is local variable to function. Code outside of the function cannot see this variable (out of scope). Then windChill is defined out of the function, but is never asigned to.
Change line windChillCalculator (T, V); to windChill = windChillCalculator (T, V);
you should put in main :
float wind_chill = windChillCalculator(T, V);
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.
This I feel is a rather complicated problem, I hope I can fit it in to small enough of a space to make it understandable. I'm presently writing code to
simulate Ideal gas particles inside a box. I'm calculating if two particles will collide having calculated the time taken for them to reach their closest point. (using an example where they have head on collision).
In this section of code I need to find if they will collide at all for two particles, before then calculating at what time and how they collide etc.
Thus for my two paricles:
Main.cpp
Vector vp1(0,0,0);
Vector vv1(1,0,0);
Vector vp2(12,0,0);
Vector vv2(-1,0,0);
Particle Particle1(1, vp1, vv1);
Particle Particle2(1, vp2, vv2);
Particle1.timeToCollision(Particle2);
Within my program I define a particle to be:
Header File
class Particle {
private:
Vector p; //position
Vector v; //velocity
double radius; //radius
public:
Particle();
Particle(double r, const Vector Vecp, const Vector Vecv);
void setPosition(Vector);
void setVelocity(Vector);
Vector getPosition() const;
Vector getVelocity() const;
double getRadius() const;
void move(double t);
double timeToCollision(const Particle particle);
void collideParticles(Particle);
~Particle();
};
Vector is another class that in short gives x, y, z values. It also contains multiple functions for manipulating these.
And the part that I need help with, within the .cpp (Ignore the cout start and letters etc, they are simple checks where my code exits for tests.)
Given the equations:
I have already written code to do the dot product and modulus for me and:
where
s is distance travelled in time tac.
double Particle::timeToCollision(const Particle particle){
Vector r2 = particle.getPosition();
Vector r1 = p;
Vector v2 = particle.getVelocity();
Vector v1 = v;
Vector r0 = r2 - r1;
Vector v = v2 - v1;
double modv;
double tca;
double result = 0;
double bsqr;
modv = getVelocity().modulus();
cout << "start" << endl;
if(modv < 0.0000001){
cout << "a" << endl;
result = FLT_MAX;
}else{
cout << "b" << endl;
tca = ((--r0).dot(v)) / v.modulusSqr();
// -- is an overridden operator that gives the negation ( eg (2, 3, 4) to (-2, -3, -4) )
if (tca < 0) {
cout << "c" << endl;
result = FLT_MAX;
}else{
cout << "d" << endl;
Vector s(v.GetX(), v.GetY(), v.GetZ());
s.Scale(tca);
cout << getVelocity().GetX() << endl;
cout << getVelocity().GetY() << endl;
cout << getVelocity().GetZ() << endl;
double radsqr = radius * radius;
double bx = (r0.GetX() * r0.GetX() - (((r0).dot(v)) *((r0).dot(v)) / v.modulusSqr()));
double by = (r0.GetY() * r0.GetY() - (((r0).dot(v)) *((r0).dot(v)) / v.modulusSqr()));
double bz=(r0.GetZ() * r0.GetZ() - (((r0).dot(v)) * ((r0).dot(v)) / v.modulusSqr()));
if (bsqr < 4 * radsqr) {
cout << "e" << endl;
result = FLT_MAX;
} else {
}
cout << "tca: " << tca << endl;
}
}
cout << "fin" << endl;
return result;
}
I have equations for calculating several aspects, tca refers to Time of closest approach.
As written in the code I need to check if b > 4 r^2, I Have made some attempts and written the X, Y and Z components of b out. But I'm getting rubbish answers.
I just need help to establish if I've already made mistakes or the sort of direction I should be heading.
All my code prior to this works as expected and I've written multiple tests for each to check.
Please inform me in a comment for any information you feel I've left out etc.
Any help greatly appreciated.
You had several mistakes in your code. You never set result to a value different from 0 or FLT_MAX. You also never calculate bsqr. And I guess the collision happens if bsqr < 4r^2 and not the other way round. (well i do not understand why 4r^2 instead of r^2 but okay). Since you hide your vector implementation I used a common vector library. I also recommend to not use handcrafted stuff anyway. Take a look into armadillo or Eigen.
Here you go with a try in Eigen.
#include <iostream>
#include <limits>
#include <type_traits>
#include "Eigen/Dense"
struct Particle {
double radius;
Eigen::Vector3d p;
Eigen::Vector3d v;
};
template <class FloatingPoint>
std::enable_if_t<std::is_floating_point<FloatingPoint>::value, bool>
almost_equal(FloatingPoint x, FloatingPoint y, unsigned ulp=1)
{
FloatingPoint max = std::max(std::abs(x), std::abs(y));
return std::abs(x-y) <= std::numeric_limits<FloatingPoint>::epsilon()*max*ulp;
}
double timeToCollision(const Particle& left, const Particle& right){
Eigen::Vector3d r0 = right.p - left.p;
Eigen::Vector3d v = right.v - left.v;
double result = std::numeric_limits<double>::infinity();
double vv = v.dot(v);
if (!almost_equal(vv, 0.)) {
double tca = (-r0).dot(v) / vv;
if (tca >= 0) {
Eigen::Vector3d s = tca*v;
double bb = r0.dot(r0) - s.dot(s);
double radius = std::max(left.radius, right.radius);
if (bb < 4*radius*radius)
result = tca;
}
}
return result;
}
int main()
{
Eigen::Vector3d vp1 {0,0,0};
Eigen::Vector3d vv1 {1,0,0};
Eigen::Vector3d vp2 {12,0,0};
Eigen::Vector3d vv2 {-1,0,0};
Particle p1 {1, vp1, vv1};
Particle p2 {1, vp2, vv2};
std::cout << timeToCollision(p1, p2) << '\n';
}
My apologies for a very poorly worded question that was to long and bulky to make much sense of. Luckily I have found my own answer to be much easier then initially anticipated.
double Particle::timeToCollision(const Particle particle){
Vector r2=particle.getPosition();
Vector r1=p;
Vector v2=particle.getVelocity();
Vector v1=v;
Vector r0=r2-r1;
Vector v=v2-v1;
double modv;
double tca = ((--r0).dot(v)) / v.modulusSqr();
double bsqr;
double result=0;
double rColTestx=r0.GetX()+v.GetX()*tca;
double rColTesty=r0.GetY()+v.GetY()*tca;
double rColTestz=r0.GetZ()+v.GetZ()*tca;
Vector rtColTest(rColTestx, rColTesty, rColTestz);
modv=getVelocity().modulus();
cout << "start " << endl;
if(modv<0.0000001){
cout << "a" << endl;
result=FLT_MAX;
}else{
cout << "b" << endl;
if (tca < 0) {
cout << "c" << endl;
result=FLT_MAX;
}else{
cout << "d" << endl;
Vector s(v.GetX(), v.GetY(), v.GetZ());
s.Scale(tca);
cout << getVelocity().GetX() << endl;
cout << getVelocity().GetY() << endl;
cout << getVelocity().GetZ() << endl;
double radsqr= radius*radius;
bsqr=rtColTest.modulusSqr();
if (bsqr < 4*radsqr) {
cout << "e" << endl;
cout << "collision occurs" << endl;
result = FLT_MAX;
} else {
cout << "collision does not occurs" << endl;
}
}
}
cout << "fin" << endl;
return result;
}
Sorry its a large section of code. Also FLT_MAX is from the cfloat lib. I didn't stat this in my question. I found this to work for several examples I calculated on paper to check.
To be Clear, the return resultand result=0 were arbitrary. I later edit to return time but for this part didn't need or want that.
Hello everyone I'm having a problem. I'm fairly new and been stuck trying to solve it.
When I run it the first part where it prints 0 for the Fahrenheit to Celsius is correct but once I input a number it just prints the number I input. I know it probably a simple answer but thank you for your time.
#include <iostream>
using namespace std;
class Temp
{
public:
Temp(); //CONSTRUCTOR: Sets private variable for Fahrenheit to 32
void InputF(float F); //Initialize Fahrenheit temperature to F
void Celsius(); //PRINTS the Celsius temperature corresponding to
// the private Fahrenheit equivalent temperature
void ChangeBy(float D); //Changes the private Fahrenheit temperature
// by D degrees.
float Fahrenheit(); // returns the value of the private Fahrenheit temp
private:
float Fah; //Fahrenheit Temperature
};
int main() {
float FF;
Temp T; // Temperature Object
T.Celsius();
cout << endl; //Note that the value will be 0 since the private variable is 32.
cout << "Input a Fahrenheit temp: ";
cin >> FF;
T.InputF(FF);
cout << T.Fahrenheit() << endl;;
T.ChangeBy(34);
cout << T.Fahrenheit() << endl;
system("Pause");
return 0;
}
Temp::Temp() {
Fah = 32;
}
void Temp::InputF(float F) {
Fah = F;
}
void Temp::Celsius() {
cout << Fah;
}
void Temp::ChangeBy(float D) {
Fah = (5.0 / 9) * (Fah - 32);
}
float Temp::Fahrenheit() {
return Fah;
}
So, one issue:
void Temp::ChangeBy(float D)
{
Fah = (5.0/9)* (Fah - 32);
}
This method does not do what you say it does in the class declaration; your comment says that it updates Fah by the number of Fahrenheit degrees passed to it.
If I may suggest the following changes:
First, have ChangeBy simply add the input value to Fah:void Temp::ChangeBy( float D )
{
Fah += D;
}
Second, have the Celcius method do the conversion and return the converted value:float Temp::Celcius()
{
return (5.0/9.0) * (Fah - 32.0);
}
Finally, in your main function, write the output of Temp::Celcius() to the output stream:std::cout << T.Celcius() << std::endl;
EDIT
I took the liberty of rewriting your code to show what I mean; there isn't enough space in a single comment to really get the point across:
#include <iostream>
using namespace std;
class Temp
{
public:
Temp( float f = 32.0 ); // slight change here
void InputF(float F);
float Celsius() const; // note return type, addition of const
void ChangeBy(float D);
float Fahrenheit() const; // note addition of const
private:
float Fah;
};
int main() {
float FF;
Temp T;
cout << T.Celsius(); // Note that we output the result of Celsius in
// exactly the same manner that we do for
// Fahrenheit below.
cout << endl;
cout << "Input a Fahrenheit temp: ";
cin >> FF;
T.InputF(FF);
cout << T.Fahrenheit() << endl;
T.ChangeBy(34);
cout << T.Fahrenheit() << endl;
return 0;
}
/**
* Slight change here; we're using a member initializer, rather than
* assigning Fah in the body of the constructor. For a simple class
* like this it doesn't matter, but when you start getting into derived
* and virtual classes, using this method will make sure things get
* initialized in the right places and in the right order.
*/
Temp::Temp( float f ) : Fah(f) {
}
void Temp::InputF(float F) {
Fah = F;
}
float Temp::Celsius() const {
return (5.0f / 9.0f) * ( Fah - 32.0f ); // use f suffix for float constants
}
void Temp::ChangeBy(float D) {
Fah += D; // Update the value of Fah by the input value; the code you
// posted isn't using the value of D to update Fah, it was
// simply converting Fah to Celsius.
}
float Temp::Fahrenheit() const {
return Fah;
}
This code builds and runs on a Linux system using g++ with the -pedantic -Wall -Werror flags.
So, I've changed the return type of Celsius from void to float; instead of having Celsius print the value, it simply returns the value to main. This way Celsius doesn't have to worry about where the output gets written (what if you wanted to write to a file instead of cout, for example), and its focus is now much narrower.
I also changed the ChangeBy function; in the implementation you pasted above, you aren't actually using the input parameter D to change the value of Fah; you're simply converting the value of Fah from Fahrenheit to Celcius.
Notice that I also added the trailing const qualifier to the Fahrenheit and Celsius methods. This indicates that these two methods will not attempt to update any data internal to Temp. It's a good idea to make such "query" methods const in this manner; it keeps you from writing code that makes changes where it shouldn't.
I have a little question about how default values are given to function parameters in C++. The problem I faced is probably due to my lack of understanding as to where the parameters are supposed to be declared/defined in the function prototype or the function header, or both? Codes are below with the errors noted:
#include <iostream>
using namespace std;
float volume(float l, float w, float h);
int main() {
float length;
float width;
float height;
cout << volume() << endl; // Here, with 'volume()' underlined, it says:
//no matching function for call to 'volume()'
cout << "Length: ";
cin >> length;
cout << "Width: ";
cin >> width;
cout << "Height: ";
cin >> height;
cout << "Volume = " << volume(length, width, height) << endl;
}
float volume(float l = 1, float w = 1, float h = 1){
float vol = l * w * h;
return vol;
}
In another attempt, here's what happened:
#include <iostream>
using namespace std;
float volume(float l = 1, float w = 1, float h = 1);
int main() {
float length;
float width;
float height;
cout << volume() << endl;
cout << "Length: ";
cin >> length;
cout << "Width: ";
cin >> width;
cout << "Height: ";
cin >> height;
cout << "Volume = " << volume(length, width, height) << endl;
}
float volume(float l = 1, float w = 1, float h = 1){ //Here, Xcode says that
// that the error is: Redefinition of default argument. < which I believe I understand.
float vol = l * w * h;
return vol;
}
In my last attempt, which is the one that worked, I did this:
#include <iostream>
using namespace std;
float volume(float l = 1, float w = 1, float h = 1);
int main() {
float length;
float width;
float height;
cout << volume() << endl;
cout << "Length: ";
cin >> length;
cout << "Width: ";
cin >> width;
cout << "Height: ";
cin >> height;
cout << "Volume = " << volume(length, width, height) << endl;
}
float volume(float l, float w, float h){
float vol = l * w * h;
return vol;
}
Could someone please explain to me the logic behind why the latter worked while the first two did not? Is there another way that the code would still work in the same way with the parameters specified elsewhere or the default values set in some place else? Are there any conventions or more favored practices in this area?
Adam
C++ and C are parsed top-down. When the compiler interprets a statement, it doesn't know about things it hasn't read yet.
In your first example, you declare a function called "volume", prototyped as taking 3 floats and returning a float. You then try to call a function called "volume" that takes no parameters, which doesn't exist yet (it would be a different function, since C++ supports polymorphism). You later define a function that can take 0, 1, 2, or 3 floats, but it is both too late and has an incompatible prototype to the first.
Your second example intuitively makes sense to be wrong, kind of like defining variables twice, but I don't have any specific information about why it is invalid code when the default values are identical.
Default parameters must be specified in the function prototype, which must occur prior to first usage in order for the compiler to know about it. Typically, you would put the prototypes with their default values in a header file that gets included above the code.
One thing to watch out for when dealing with default parameters from a shared header file, especially if you use it with dynamic libraries: The default values for the parameters are stored with the caller, and not the function being called. That is, if you update the function with new default values and don't rebuild the code calling that function, the old defaults will still be used by the calling code.
Adding to the above answer from Bjarne Stroustrup
A default argument is type checked at the time of the function declaration and evaluated at the time of the call. Default arguments may be provided for trailing arguments only. For example:
int f (int, int =0 , char * =0 ); // ok
int g (int =0 , int =0 , char *); // error
int h (int =0 , int , char * =0 ); // error
A default argument can be repeated in a subsequent declaration in the same scope but not changed.
For example:
void f (int x = 7 );
void f (int = 7 ); // ok
void f (int = 8 ); // error: different default arguments
void g () { void f (int x = 9 ); // ok: this declaration hides the outer one }
Declaring a name in a nested scope so that the name hides a declaration of the same name in an outer scope is error prone.
Default values could be defined in function declaration, as you done in your third attempt. This means usually they're appeared in header files, although this is not a rule.
Note that function declarations are scoped. This means that you could have more than one declaration for a function as long as they have different scopes:
void f(int);
int main() {
f(3); // argument should specified.
void f(int = 1);
f(); // calls f(1)
}
void f(int n = 2) {
}
void g() {
f(); // calls f(2)
}
In your second attempt you put default values on both declaration and definition of the function. This cause the compiler to confused because they are in the same scope.