So I'm a total noob at C++, I decided to learn C++ and skipped directly to the Object-oriented programming. I'm coding a class called KineticEnergy that has a constructor with the parameters x and y which is assigned to the variables mass and velocity.
I have a class method called result() which calculates the Kinetic Energy using its formula. I want to call the parameters from my constructor within the formula but I have no idea what I'm exactly doing here (bad english, don't know how to explain). I am getting errors like "[Error] x was not declared in this scope". Here is the code I written:
#include <iostream>
#include <cmath>
using namespace std;
class KineticEnergy
{
public:
double mass;
double velocity;
KineticEnergy(double x, double y) {
mass = x;
velocity = y;
}
double result()
{
return (1/2) * (x * (pow(y, 2)));
} // What am I gonna do here for this to work?
};
int main()
{
double a = 12.1;
double b = 6.4;
KineticEnergy ke(a, b);
cout << ke.result();
return 0;
}
It is not necessary. your constructor parameters is saved in "mass" and "velocity" as class members.
double result()
{
return (1./2.) * (mass * (pow(velocity , 2.)));
}
Parameters of the parameterized constructor are not member variables. That's why you are storing param values in member variables inside of the parameterized constructor. So that, you should use member variables inside of the result() function.
try this
#include <iostream>
#include <cmath>
using namespace std;
class KineticEnergy
{
public:
double mass;
double velocity;
KineticEnergy(double x, double y) {
mass = x;
velocity = y;
}
double result()
{
return 0.5 * (mass * pow(velocity, 2));
}
};
int main()
{
double a = 12.1;
double b = 6.4;
double Result;
KineticEnergy ke(a, b);
Result = ke.result();
cout << Result;
}
x and y were declared in your constructor, therefore only known by your constructor. you cannot use them outside of it. however, mass and velocity are known variables of your class and can be used anywhere as long as they are public.
in your main you give mass and velocity of your ke object values, that's why you can call any method of your class that uses these variables after(again, as long as they're public)
Related
In the shape.cpp I need set a default constructor for class Point, But I don't know how to do that.
Thanks
Point::Point(double _f, double _g){
f = 1;
g = 1;
}
Rectangle::Rectangle():Point(1, 1) {
x = 1;
y = 1;
}
Rectangle::Rectangle( Point q, double l, double w):x(l),y(w),Point(q) {
}
#include <iostream>
using namespace std;
class Point{
int f,g; //declaring point(f,g)
public :
Point(); //This will be your default constructor
Point(double _f,double _g); // Constructor for class Point
int getf(){ //just for purpose of display function() below. You can remove this once you understand code.
return f;
}
int getg(){ //just for purpose of display function() below. You can remove this once you understand code.
return g;
}
};
class Rectangle{
double l,w; //declaring variable to store length and width of Rectangle
Point pt; //whatever your use of point is
public :
Rectangle(Point q,double l,double w); //constructor for class Rectangle
void display(){ // displaying the class...just for demonstration
cout<<"l = "<<l<<endl;
cout<<"w = "<<w<<endl;
cout<<"pt = ("<<pt.getf()<<", "<<pt.getg()<<")\n";
}
};
//Defining the constructor of class Point
Point::Point(double _f, double _g):f(_f),g(_g){} // I have used initialiser list here
Point::Point():f(0),g(0){} // (your needed default constructor)
Rectangle::Rectangle( Point q, double l, double w):l(l),w(w),pt(q) {} //Defining the constructor of class Rectangle
int main()
{ //Demonstrating object creation and displaying of object r of class rectangle
Point p(1,2);
Rectangle r(p,5,10);
r.display();
}
I have attached the code that would help you understand about constructors and how to define them.
Hope this solves your question !
class Point{
int f,g;
public:
Point();
};
Point::Point(){
f = 1;
g = 1;
}
int main(){
Point *p = new Point() ;
}
I'm trying to pass function of multiple arguments to other function. I know how to pass a function of single argument function to other function as it was described in C++ primer plus book.
However, I get an error when I'm trying to pass multiple arguments with class(poly_3d) to NR_method function.
#include <iostream>
#define log(x) std::cout<<x<<std::endl;
class constants {
public:
double A;
double B;
double C;
};
double poly_3d(double x, constants cst);
double NR_method(double a, double(*poly_3d)(double));
int main() {
constants cst;
cst.A = 2;
cst.B = -8;
cst.C = 10;
NR_method(3.2, poly_3d);
system("PAUSE");
return 0;
}
double poly_3d(double x, constants cst) {
double y = 3 * cst.A*x*x + 2 * cst.B*x + cst.C;
return y;
}
double NR_method(double a, double (*poly_3d)(double)) {
double c = (*poly_3d)(a);
return c;
}
So the error I'm getting is from NR_method(3.2, poly_3d) in main function. I know that if poly_3d was single arg, this would work.
If this is a horrible way to write codes, then any directions towards learning C++ more effectively for newbies would be much appreciated! Thanks
Take a look at the following code. We're using a template to make things look nicer.
#include <iostream>
#define log(x) std::cout<<x<<std::endl;
class constants {
public:
double A;
double B;
double C;
};
/// Note that we take a ref now, no need to copy cst.
double poly_3d(double x, constants & cst)
{
double y = 3 * cst.A*x*x + 2 * cst.B*x + cst.C;
return y;
}
/// Note that we take a ref now, no need to copy cst.
template <class F>
double NR_method(double a, constants & cst, F func)
{
return func(a, cst);
}
int main() {
constants cst;
cst.A = 2;
cst.B = -8;
cst.C = 10;
NR_method(3.2, cst, &poly_3d);
system("PAUSE");
return 0;
}
You are declaring the function poly_3d with 2 arguments but passing only one. I made a few changes on the code for you
#include <iostream>
#define log(x) std::cout<<x<<std::endl;
class constants {
public:
double A;
double B;
double C;
};
double poly_3d(double x, constants cst);
double NR_method(double a, constants cst, double(*poly_3d)(double, constants));
int main() {
constants cst;
cst.A = 2;
cst.B = -8;
cst.C = 10;
printf("%f", NR_method(3.2, cst, poly_3d));
system("PAUSE");
return 0;
}
double poly_3d(double x, constants cst) {
double y = 3 * cst.A*x*x + 2 * cst.B*x + cst.C;
return y;
}
double NR_method(double a, constants cst, double (*poly)(double, constants)) {
return (*poly)(a, cst);
}
Let's start by simplifying your code. (A minimal example removes distractions, allowing you to better focus on the actual issue.) It looks like you started to do this, but it can be taken further. After removing some stuff that is not needed to reproduce the compile error:
class constants {};
double poly_3d(double x, constants cst);
double NR_method(double a, double(*poly_3d)(double));
int main() {
NR_method(3.2, poly_3d);
}
double poly_3d(double x, constants /*cst*/) {
return 3 * x;
}
double NR_method(double a, double (*poly_3d)(double)) {
return (*poly_3d)(a);
}
Now let's look at the error message:
error: invalid conversion from 'double (*)(double, constants)' to 'double (*)(double)'
This comes with an indication that the conversion is from poly_3d to the second argument of NR_method. If you look at those things, yes, that is the conversion you requested. The argument list for poly_3d is (double, constant), while the declared argument list for the second argument is just (double). There is a mismatch, which makes the conversion invalid. It's not all that different from the single-parameter case: the signatures must match. You can solve this by changing the argument's signature to math that of poly_3d.
Now, if you just make the signatures match, there is another problem in that NR_method does not have a constants value available. That is probably a logical error for you to work out. For a quick workaround to show the elimination of the compiler error, I'll add a local variable.
class constants {
};
double poly_3d(double x, constants cst);
double NR_method(double a, double(*poly_3d)(double, constants)); // <-- Desired signature
int main() {
NR_method(3.2, poly_3d);
}
double poly_3d(double x, constants /*cst*/) {
return 3.0 * x;
}
double NR_method(double a, double (*poly_3d)(double, constants)) {
constants cst; // <-- Allows this to compile, but probably not what you want.
return (*poly_3d)(a, cst); // <-- Needed a second parameter here.
}
There are ways to make this work nicer (for example, a std::function may be more convenient than a function pointer), but explaining those would fall outside the scope of this question, especially since some decisions would depend on the bigger picture.
I'm facing a big issue which I have been trying to solve in vain for 3 days. I've got a CDS class with a intensity_func member function and a big_gamma member function which is basically the integral of the member intensity_func function.
#include <vector>
#include <cmath>
using namespace std
class CDS
{
public:
CDS();
CDS(double notional, vector<double> pay_times, vector<double> intensity);
~CDS();
double m_notional;
vector<double> m_paytimes;
vector<double> m_intensity;
double intensity_func(double);
double big_gamma(double);
};
And here is the CDS.cpp with the definition of the intensity_func member function :
#include <vector>
#include <random>
#include <cmath>
#include "CDS.h"
double CDS::intensity_func(double t)
{
vector<double> x = this->m_intensity;
vector<double> y = this->m_paytimes;
if(t >= y.back() || t< y.front())
{
return 0;
}
else
{
int d=index_beta(y, t) - 1;
double result = x.at(d) + (x.at(d+1) - x.at(d))*(t - y.at(d))/ (y.at(d+1) - y.at(d));
return result;
}
I have implemented in another source file a function to integrate function and the index_beta function used in the intensity_func member function (using the Simpson's rule). Here is the code:
double simple_integration ( double (*fct)(double),double a, double b)
{
//Compute the integral of a (continuous) function on [a;b]
//Simpson's rule is used
return (b-a)*(fct(a)+fct(b)+4*fct((a+b)/2))/6;
};
double integration(double (*fct)(double),double a, double b, double N)
{
//The integral is computed using the simple_integration function
double sum = 0;
double h = (b-a)/N;
for(double x = a; x<b ; x = x+h) {
sum += simple_integration(fct,x,x+h);
}
return sum;
};
int index_beta(vector<double> x, double tau)
{
// The vector x is sorted in increasing order and tau is a double
if(tau < x.back())
{
vector<double>::iterator it = x.begin();
int n=0;
while (*it < tau)
{
++ it;
++n; // or n++;
}
return n;
}
else
{
return x.size();
}
};
So, what I would like to have in my CDS.cpp to define the big_gamma member function is :
double CDS::big_gamma(double t)
{
return integration(this->intensity, 0, t);
};
But obviously, it does not work and I get the following error message : reference to non static member function must be called. I've then tried to turn the intensity member function into a static function but new problems come out: I can't used this->m_intensity and this->m_paytimes anymore as I get the following error message: Invalid use of this outside a non-static member function.
double (*fct)(double) declares an argument of type "pointer-to-function". You need to declare that as a "pointer-to-member function" instead: double (CDS::*fct)(double). Furthermore, you need an object on which you call the pointer-to-member:
(someObject->*fct)(someDouble);
I have this class "Point" which takes in x and y as arguments.
However I need to create a constructor that initializes them to random values.
I don't know exactly how it is done. Here's my code:
I created constructors but I'm getting values that are absurd even when I set x and y.
#include <iostream>
#include <cmath>
#include <ctime>
using namespace std;
class Point
{
private:
double x;
double y;
public:
double get_x()
{
return x;
}
void set_x (double x)
{
this->x = x;
}
double get_y()
{
return y;
}
void set_y(double y)
{
this->y = y;
}
double distanceTo(Point p)
{
double x2 = p.get_x();
double y2 = p.get_y();
return sqrt( pow(x-x2,2) + pow(y-y2,2) );
}
Point(double x, double y)
{
x = rand()*1.0 / RAND_MAX * 100;
y = rand()*1.0 / RAND_MAX * 100;
}
Point(){};
};
void main()
{
Point a(1.2,0.5);
Point b;
b.set_x(1);
b.set_y(1);
cout << a.distanceTo(b);
system ("Pause");
}
That's because you aren't initializing your member variables, but changing a copy of the variables that are being passed into the constructor. Hence you're seeing garbage values as x and y (the class versions) are never initialized. You should change this to:
Point()
{
x = rand()*1.0 / RAND_MAX * 100;
y = rand()*1.0 / RAND_MAX * 100;
}
Further, you never call srand() anywhere - you need to do this at some point to properly seed the random generator.
Mistake: You changing local copies of variables passed to constructor by value (they have same name as member variables) and member variables left uninitialized so your program has undefined behavior.
How to fix: You must explicitly indicate what variable you are assigning to. Also, overload you constructor, so you will have one (default) for random values, and one for user-predefined.
Also:
it's better to pass values that not going to be changed in function as constant
you might want pass double by reference, not by value
use initializers lists instead of assignment in constructor body
when using constant references here you don't need to resolve names because you can't change constant values, so compiler will change member variables
Code:
class Point
{
public:
Point() :
x(rand()*1.0 / RAND_MAX * 100),
y(rand()*1.0 / RAND_MAX * 100)
{
}
Point(const double& x, const double& y) :
x(x),
y(x)
{
}
private:
double x, y;
};
int main()
{
Point pt(42, 3.14);
Point pt_random;
}
Same in accessor functions:
double GetX() const { return x; }
void SetX(const double& x) { Point::x = x; }
Because you're altering temporary variables in the constructor (name collision in the same scope). Try:
Point(double x, double y)
{
Point::x = rand()*1.0 / RAND_MAX * 100;
Point::y = rand()*1.0 / RAND_MAX * 100;
}
But that completely disregards arguments given to the constructor. But since now you know how to differentiate between different scopes of variables, you can go on from here, I believe.
Your default constructor does nothing. It doesn't even initialize the values which means they are going to have an unspecified value.
Your constructor taking two arguments just assigns to the arguments, because their names shadow the names of the members.
change
Point(){};
to
Point()
{
x = rand()*1.0 / RAND_MAX * 100;
y = rand()*1.0 / RAND_MAX * 100;
}
also I would advice to change your arguments\members name to avoid mistakes. I personally like to use m_ for members :
private:
double m_x;
double m_y;
You are getting a 'name collision'. In this function
Point(double x, double y)
{
x = rand()*1.0 / RAND_MAX * 100;
y = rand()*1.0 / RAND_MAX * 100;
}
The compiler is doesn't know which x you mean when you assign. The language rules will say that the input arguments should be assigned - but you should not rely on this - because it is needlessly confusing.
A good practice is to adopt a naming convention for member variables. Two common ones are to prefix members with "m" or "_". I like "m" personally.
Then your code becomes:
class Point
{
public:
double mX;
double mY;
Point(double x, double y)
{
mX = rand()*1.0 / RAND_MAX * 100;
mY = rand()*1.0 / RAND_MAX * 100;
}
}
Also the constructor arguments in this case are redundant, and can be removed.
Some of the other answers above are also correct - but it is a sign of bad class design if you have to explicity scope names ( e.g. Point:: ) in simple functions.
I've created a global function, CallPrice(args). I have a class, EuropeanOption, and I have a class function called CallPrice, which should call the global function using variables from the EuropeanOption class, and return the CallPrice. I'm getting an error, "the global scope has no "CallPrice".
I think this is a common problem. I searched other threads, which said adding :: should solve the problem, but it's not working here for me. Could you identify the cause of the error? Do I need to make this a friend function or some other workaround?
Thanks!
Header:
#ifndef EuropeanOption_HPP
#define EuropeanOption_HPP
#include <iostream>
#include <string>
#include <vector>
#include <cmath>
#include <boost/math/distributions/normal.hpp>
using namespace boost::math;
using namespace std;
namespace CLARK
{
struct EquityParms
{
double T; // years until expiry
double K; // strike price
double sig; // vol
double r; // risk free rate
double b; // cost of carry
};
// Global Call function
const double CallPrice(double T, double K, double sig, double r, double b, double EquityPrice);
class EuropeanOption
{
private:
double T; // years until expiry
double K; // strike price
double sig; // vol
double r; // risk free rate
double b; // cost of carry
double S; // current equity price
double ExactCallPrice;
public:
EuropeanOption(); // default constructor (empty)
EuropeanOption(const EquityParms& data, double EquityPrice); // constructor that sets parms
void copy(const EuropeanOption& source);
~EuropeanOption();
void init(const EquityParms& data, double EquityPrice); // initialize EquityParms
const double CallPrice(); // trying to call global function in this function
};
}
#endif
Source:
#include "EuropeanOption_H.hpp"
namespace CLARK
{
const double CallPrice(double T, double K, double sig, double r, double b, double EquityPrice)
{// Global Function
double temp = sig * sqrt(T);
double d1 = (log(EquityPrice / K) + (r + (sig*sig) * 0.5) * T) / temp;
double d2 = d1 - temp;
normal_distribution<> myNormal(0,1);
return (EquityPrice * cdf(myNormal,d1)) - (K * exp((b - r) * T) * cdf(myNormal, d2));
}
EuropeanOption::EuropeanOption()
{// default constructor
cout << "Default constructor call" << endl;
}
EuropeanOption::EuropeanOption(const EquityParms& data, double EquityPrice)
{// constructor that sets parms
init(data, EquityPrice);
}
void EuropeanOption::copy(const EuropeanOption& source)
{
T = source.T;
K = source.K;
sig = source.sig;
r = source.r;
S = source.S;
b = source.b;
}
EuropeanOption::~EuropeanOption()
{
}
void EuropeanOption::init(const EquityParms& data, double EquityPrice)
{
T = data.T;
K = data.K;
sig = data.sig;
r = data.r;
S = EquityPrice;
b = data.b;
}
const double EuropeanOption::CallPrice()
{ // trying to call global function in this function
return ::CallPrice(T, K, sig, r, b, S); // the global scope has no "CallPrice" ???
}
}
CallPrice is in namespace CLARK. So try
CLARK::CallPrice(/* ... */);
You have declared the global CallPrice in the namespace CLARK. The syntax ::CallPrice tries to use a function CallPrice defined in the global namespace, or an anonymous namespace. Instead, use CLARK::CallPrice.
You are in the namespace CLARK:
return CLARK::CallPrice(T, K, sig, r, b, S);