Implementing a European Option class - c++

I need implement the class Option_Pricer that encapsulates all the functions relevant to price both call and put options. The teacher is giving me a code listing (.cpp file) that I have to turn into a class. All the functions that I used in my class are therefore coming from the teacher. I simply have to implement them as a class.
Here is what I have done so far: I have split the code into two different files. One is called option_pricer.hpp and is used as an header for the main file option_pricer.cpp.
//option_pricer.hpp
#define _USE_MATH_DEFINES
#include <iostream>
#include <cmath>
class Option_Pricer {
private:
void init();
public:
double S;
double K;
double r;
double v;
double T;
double x;
double j;
public:
//Constructors
call_price();
put_price();
norm_pdf();
norm_cdf();
d_j() const;
// Assignment operator
call_price& operator = (const call_price& call);
put_price& operator = (const put_price& put);
};
Here is the main file:
//option_pricer.cpp
#define _USE_MATH_DEFINES
#include <iostream>
#include <cmath>
#include "option_pricer.hpp"
double Option_Pricer::norm_pdf(const double& x) const {
return (1.0/(pow(2*M_PI,0.5)))*exp(-0.5*x*x);
}
double Option_Pricer::norm_cdf(const double& x) const {
double k = 1.0/(1.0 + 0.2316419*x);
double k_sum = k*(0.319381530 + k*(-0.356563782 + k*(1.781477937 + k*(-1.821255978 + 1.330274429*k))));
if (x >= 0.0) {
return (1.0 -(1.0/(pow(2*M_PI,0.5)))*exp(-0.5*x*x) * k_sum);
}
else {
return 1.0 - norm_cdf(-x);
}
}
double Option_Pricer::d_j(const int& j, const double& S, const double& K, const double& r, const double& v, const double& T) const {
return (log(S/K) + (r + (pow(-1,j 1))*0.5*v*v)*T)/(v*(pow(T,0.5)));
}
double Option_Pricer::call_price(const double& S, const double& K, const double& r, const double& v, const double& T) const {
return S * norm_cdf(d_j(1, S, K, r, v, T))-K*exp(-r*T) * norm_cdf(d_j(2, S, K, r, v, T));
}
double Option_Pricer::put_price(const double& S, const double& K, const double& r, const double& v, const double& T) const {
return -S*norm_cdf(-d_j(1, S, K, r, v, T))+K*exp(-r*T) * norm_cdf(-d_j(2, S, K, r, v, T));
}
int main() {
Option_Pricer p;
p.S = 100.0;
p.K = 100.0;
p.r = 0.05;
p.v = 0.2;
p.T = 1.0;
double call_price = p.call_price();
double call_put = p.put_price();
// Finally we output the parameters and prices
std::cout << "Underlying: " << p.S << std::endl;
std::cout << "Strike: " << p.K << std::endl;
std::cout << "Risk-Free Rate: " << p.r << std::endl;
std::cout << "Volatility: "<< p.v << std::endl;
std::cout << "Maturity: " << p.T << std::endl;
std::cout << "Call price: " << call_price << std::endl;
std::cout << "Put price: " << call_put << std::endl;
return 0;
}
However, as you can guess, my code isn't compiling really well. My most common error is the following:
option_pricer.cpp:7:8: error: no declaration matches ‘double Option_Pricer::norm_pdf(const double&) const’
7 | double Option_Pricer::norm_pdf(const double& x) const {
| ^~~~~~~~~~~~~
I don't understand how I should call the norm_pdf from outside of the header (same question for norm_cdf and d_j).
I'm fairly new to C++ (was using Python before) and therefore don't understand yet how am I supposed to access the variables (S, K,...) from outside of my class.
Help will be appreciated! Thank you!

You need to make and understand the distinction between a class and an object. Very simply, an object is a collection of values in memory, and a class is a description of those values and of code that will use data organized according to the class description.
So, since Option_Pricer is a class, it doesn't make sense to say Option_Pricer.S = 100.0; in your main() method. You need to create an object of type Option_Pricer, and then fill that object's memory region with the values you want. A common method for doing that - especially in your case where you are simply initializing the object with numeric data - is to create and use a constructor, although you could modify your init() method to take arguments and set values and that would be fine too. You can even set the values one-by-one as you have done, since you made the values public, but you have to modify the object, not the class.
Ex.
int main()
{
Option_Pricer p(100.0, 100.0, 0.5, 0.2, 1.0);
double call_price = p.call_price();
// or
Option_Pricer p2;
p2.init(100.0, 100.0, 0.5, 0.2, 1.0);
double call_price2 = p2.call_price();
// or, if you like typing or want the meaning of the numbers to be super clear
Option_Pricer p3;
p3.S = 100.0;
p3.K = 100.0;
p3.r = 0.05;
p3.v = 0.2;
p3.T = 1.0;
// ...
This doesn't address everything that's wrong with your code, but I'd start by addressing the above. I think the problems that others are pointing out will be easier to sort out once you get the concept of an object squared away.

Related

Efficient non-trivial initialization of multiple members in C++ initialization lists

Suppose I want to write a class that represents an immutable normalized (norm == 1) vector in two dimensions along with a mutable int:
#include <cmath>
#include <iostream>
double norm2d(double x, double y)
{
return sqrt(x*x + y*y);
}
class NormalizedVector {
public:
NormalizedVector(double x, double y, int some_int)
: m_x(x / norm2d(x, y)), m_y(y / norm2d(x, y)), m_some_int(some_int){};
void set_some(int i) { m_some_int = i; }
private:
const double m_x;
const double m_y;
int m_some_int;
friend std::ostream& operator<< (std::ostream& os, const NormalizedVector& v) {
return os << "(" << v.m_x << "," << v.m_y << ")" << " : " << v.m_some_int;
}
};
int
main() {
NormalizedVector v { 1, 1 , 42};
std::cout << v << std::endl;
v.set_some(23);
std::cout << v << std::endl;
return 0;
}
Is it in this situation possible to avoid calling norm2d(x, y) twice in the ctor while still using initialization lists? Note that default-constructing members and assigning them in the ctor's body is not possible because the vector components are const.
I am well aware that this MWE is not very realistic but in the past I have for several times stumbled upon a situation where one function (or "some code") was required to compute values for multiple members in the initialization list and where in-body-assigning them was not an option because the corresponding members where either const or not zero-cost-default-constructable.
Yes, you can have a private constructor that takes an additional parameter, and delegate to that.
class NormalizedVector {
public:
NormalizedVector(double x, double y, int some_int)
: NormalizedVector(x, y, some_int, norm2d(x, y)) {};
void set_some(int i) { m_some_int = i; }
private:
NormalizedVector(double x, double y, int some_int, double norm)
: m_x(x / norm), m_y(y / norm), m_some_int(some_int){};
const double m_x;
const double m_y;
int m_some_int;
friend std::ostream& operator<< (std::ostream& os, const NormalizedVector& v) {
return os << "(" << v.m_x << "," << v.m_y << ")" << " : " << v.m_some_int;
}
};

Eigen::VectorXd and Boost::Odeint, not working

I am testing with Eigen::VectorXd as state_type for boost::odeint. I use this code:
#include <Eigen/Eigen>
#include <boost/numeric/odeint.hpp>
#include <boost/numeric/odeint/external/eigen/eigen_algebra.hpp>
#include <iostream>
#include <vector>
template<class T>
struct push_back_state_and_time
{
std::vector<T>& m_states;
std::vector< double >& m_times;
push_back_state_and_time( std::vector<T> &states ,std::vector<double> &times )
: m_states(states) , m_times(times) { }
void operator()(const T &x ,double t )
{
m_states.push_back(x);
m_times.push_back(t);
}
};
template<class T>
struct write_state
{
void operator() ( const T &x, const double t ) {
std::cout << t << "\t";
for(size_t i = 0; i < x.size(); ++i)
std::cout << x[i] << "\t";
std::cout << std::endl;
};
};
template<class T>
class odeClass {
private:
double Ka, Kel, Vd;
public:
odeClass(double ka, double kel, double vd) : Ka(ka), Kel(kel), Vd(vd) {};
void operator() (const T &x, T &dxdt, const double t) {
dxdt[0] = - Ka * x[0];
dxdt[1] = Ka * x[0] - Kel * x[1];
};
};
void testODE_Eigen() {
double Ka = 0.195, Vd = 13.8, Kel = 0.79 / Vd;
Eigen::VectorXd x(2);
x << 40 / Vd, 0.0;
odeClass<Eigen::VectorXd> myClass(Ka, Kel, Vd);
boost::numeric::odeint::runge_kutta4<Eigen::VectorXd, double, Eigen::VectorXd, double, boost::numeric::odeint::vector_space_algebra> stepper;
size_t steps = integrate_adaptive( stepper, myClass, x ,0.0 ,100.0 ,0.5 ,write_state<Eigen::VectorXd>() );
}
void testODE_Vector() {
double Ka = 0.195, Vd = 13.8, Kel = 0.79 / Vd;
std::vector<double> x = { 40 / Vd, 0.0 };
odeClass<std::vector<double>> myClass(Ka, Kel, Vd);
boost::numeric::odeint::runge_kutta4<std::vector<double>> stepper;
size_t steps = integrate_adaptive( stepper, myClass, x ,0.0 ,100.0 ,0.5 ,write_state<std::vector<double>>() );
}
int main()
{
testODE_Eigen();
return 0;
}
When running the function testODE_Vector();, it works perfectly, but when runningtestODE_Eigen();` I get the first integration step, one assertion stop: "Assertion failed: index >= 0 && index < size(), file C:\Eigen-3.3.7\Eigen\src\Core\DenseCoeffsBase.h, line 408.", and a windows message saying that the application has stop working, with no clue, if a use Code::Blocks. If I run the same on Visual Studio 2017 console application, I get one error saying Cannot write on a memory address without printing anything.
Any clues?
Thank you.
It looks like you are failing an assertion inside the Eigen library you are using. With a message like Assertion failed: index >= 0 && index < size() the library is probably trying to iterate over a vector internally and checks that the vector is valid before trying to access it. I would check the objects you are passing in and make sure they are valid.
It looks like one of the main differences in the two function testODE_Vector() and testODE_Eigen() is the way that you create that x. I'm not sure what this line
x << 40 / Vd, 0.0; is intended to do, but I would start there and verify that the value of x is right before it's passed into integrate_adaptive
My answer is a little late but in case someone else runs into this issue, here's what I found.
The issue seems to be that OdeInt can't handle properly the dynamic size with Eigen vectors and matrices. Therefore when creating dxdt, it creates an empty dynamic matrix or vector. This leads to an issue in your operator overload, where you try to access an element of dxdt where it contains none.
A quick fix I found was to use the resize() function (or conservativeResize()) to make sure dxdt has the proper size:
void operator() (const T &x, T &dxdt, const double t) {
dxdt.resize(x.size())
dxdt[0] = - Ka * x[0];
dxdt[1] = Ka * x[0] - Kel * x[1];
};
Note that if you want to use matrices instead of vectors you will have to use x.rows() and x.cols() instead of x.size().

operator<<() not resolving from template due to inheritance

I'm working with a set of classes and my main code looks like this:
main.cpp
#include "calc.h"
int main() {
neg_inf nif;
pos_inf pif;
limit<double, infinity> l( 3.4, nif, pif, 2.2 )
std::cout << "value dx = " << l.value() << '\n'
<< "lower lim = " << l.lower() << '\n'
<< "upper lim = " << l.upper() << '\n'
<< "step_size = " << l.step() << '\n';
return EXIT_SUCCESS;
}
The expected output should be:
value dx = 3.4
lower lim = -inf
upper lim = inf
step_size = 2.2
Here are my classes:
calc.h
#pragma once
#include <cmath>
#include <iostream>
#include <limits>
#include <type_traits>
struct infinity {
protected:
infinity() = default;
};
struct pos_inf : public infinity {
constexpr double operator()() { return std::numeric_limits<double>::infinity(); }
};
struct neg_inf : public infinity {
constexpr double operator()() { return -std::numeric_limits<double>::infinity(); }
};
std::ostream& operator<<( std::ostream& os, const pos_inf& inf );
std::ostream& operator<<( std::ostream& os, const neg_inf& inf );
template<typename dX, class bound>
class limit {
dX dx;
bound lowerBound;
bound upperBound;
double step_size;
public:
limit( dX x, bound lower, bound upper, double step = 1 ) :
dx{ x }, lowerBound{ lower }, upperBound { upper }, step_size { step }
{}
dX value() const { return dx; }
bound lower() const { return lowerBound; }
bound upper() const { return upperBound; }
double step() const { return step_size; }
};
calc.cpp
#include "calc.h"
std::ostream& operator<<( std::ostream& os, const pos_inf& inf ) {
// originally intended to do:
// return os << inf(); // but fails to compile
auto v = pos_inf()(); // this works
return os << v;
}
std::ostream& operator<<( std::ostream& os, const neg_inf& inf ) {
// same as above...
auto v = neg_inf()();
return os << v;
}
However in the main.cpp Visual Studio 2017 is generating this compiler error:
c:\***\main.cpp(33): error C2679: binary '<<': no operator found which takes a right-hand operand of type 'bound' (or there is no acceptable conversion)
1> with
1> [
1> bound=infinity
1> ]
based on this line of code:
<< "lower lim = " << l.lower() << '\n'
and is failing from l.lower()
However if I do this in main:
#include "calc.h"
int main() {
neg_inf nif;
pos_inf pif;
std::cout << nif << '\n' << pif << '\n'
return EXIT_SUCCESS;
}
I am getting the output:
-inf
inf
This tells me that my operator<<() are working for the inherited structs, however when I pass it's parent type as a template argument and pass the derived types into the constructor of my limit class, the operator<<() are not resolving. It appears to be an ambiguity problem but I'm not sure how to resolve this. What am I missing or overlooking here?
As a side note which is outside of this question, is there a more elegant way to represent -/+inf? I'm using inheritance here because + and - inf are not numbers but more of a concept, they are similar to each other but point in different directions. So when I pass an infinity type as a template argument I'd like to be able to set the lower bound to -inf and the upper bound to +inf. I want the bound type to be a template because I might want to use integer bounds or double bounds for example between [-1,1] or [0.0,1.0] in which these are all numeric bounds. I'm not sure how else to express infinity in a more elegant way and any tips or suggestions will be appreciated.
Do not overload operators for the subclasses that way. Use a virtual method to do the output and use the generic type with the overload operator that calls the virtual method:
class infinity {
public:
virtual ostream &printTo(ostream &o) const = 0;
};
ostream &operator<<(ostream &o,const infinity &i) {
return i.printTo(o);
}
class neg_inf : public infinity {
public:
virtual ostream &printTo(ostream &o) const {
// do what you want
return o;
}
};
Well, you have made overloads for operator<< taking const pos_inf& inf and const neg_inf& inf, but you are using infinity as the template type, thus your lower() method returns infinity. Of course the your operator overloads will not be used since they are derived types from infinity. Why not just overload the operator<< for infinity ?
Some quick ideas how to solve this:
Making the double operator()() virtual. But you can't mix that with constexpr.
Using template<typename dX, class lower_bound, class upper_bound> for limits class to actually specify the types for both bounds, then your lower and upper methods can return the pos_inf and neg_inf types and your current operators will work. Also, for simplicity you can also default the second type fo the first if the types will not always differ - template<typename dX, class lower_bound, class upper_bound = lower_bound>.
After giving more though about the design - why then not actually make the infinity class templated (since I assume you want it to match dX, and implement the limits there?
#include <cmath>
#include <iostream>
#include <limits>
#include <type_traits>
template<typename T>
struct infinity {
public:
infinity() = default;
constexpr double lower()
{
return -std::numeric_limits<T>::infinity();
}
constexpr double upper()
{
return std::numeric_limits<T>::infinity();
}
};
template<typename dX>
class limit {
dX dx;
double step_size;
public:
limit(dX x, double step = 1) :
dx{ x }, step_size{ step }
{}
dX value() const { return dx; }
dX lower() const { return infinity<dX>().lower(); }
dX upper() const { return infinity<dX>().upper(); }
double step() const { return step_size; }
};
int main() {
limit<double> l(3.4, 2.2);
std::cout << "value dx = " << l.value() << '\n'
<< "lower lim = " << l.lower() << '\n'
<< "upper lim = " << l.upper() << '\n'
<< "step_size = " << l.step() << '\n';
return EXIT_SUCCESS;
}
Making lower/upper return dX. That way you actually leave the resolution from the bound type to your needed value type inside the template, and you can mix infinite and non-infinite limits.
#include <cmath>
#include <iostream>
#include <limits>
#include <type_traits>
struct pos_inf {
constexpr operator double() const { return std::numeric_limits<double>::infinity(); }
};
struct neg_inf {
constexpr operator double() const { return -std::numeric_limits<double>::infinity(); }
};
template<typename dX, typename upper_bound = dX, typename lower_bound = dX>
class limit {
dX dx;
upper_bound lowerBound;
lower_bound upperBound;
double step_size;
public:
limit(dX x, upper_bound lower, lower_bound upper, double step = 1) :
dx{ x }, lowerBound{ lower }, upperBound{ upper }, step_size{ step }
{}
// with infinity these two will invoke operator double(), with actual double it will return the fixed value
dX lower() const { return lowerBound; }
dX upper() const { return upperBound; }
dX value() const { return dx; }
double step() const { return step_size; }
};
int main() {
limit<double, pos_inf, neg_inf> l(3.4, pos_inf(), neg_inf(), 2.2); // infinity
limit<double> l2(3.4, 1, 5, 2.2); // fixed values
std::cout << "value dx = " << l.value() << '\n'
<< "lower lim = " << l.lower() << '\n'
<< "upper lim = " << l.upper() << '\n'
<< "step_size = " << l.step() << '\n';
return EXIT_SUCCESS;
}
I think you are constraining yourself too much: you can drop the base class, add operator<< for both pos_inf and neg_inf and add an extra type to limit, in this way you can have the two bounds of different types. Here is what I mean:
Calc.h
#pragma once
#include <cmath>
#include <iostream>
#include <limits>
#include <type_traits>
struct pos_inf {
constexpr double operator()() const { return std::numeric_limits<double>::infinity(); }
};
struct neg_inf {
constexpr double operator()() const { return -std::numeric_limits<double>::infinity(); }
};
// Both operators defined
std::ostream& operator<<(std::ostream& os, const pos_inf& inf);
std::ostream& operator<<(std::ostream& os, const neg_inf& inf);
//extra template type in limit
template<typename dX, class lowerBoundType, class UpperBoundType>
class limit {
dX dx;
lowerBoundType lowerBound;
UpperBoundType upperBound;
double step_size;
public:
limit(dX x, lowerBoundType lower, UpperBoundType upper, double step = 1) :
dx{ x }, lowerBound{ lower }, upperBound{ upper }, step_size{ step }
{}
dX value() const { return dx; }
lowerBoundType lower() const { return lowerBound; }
UpperBoundType upper() const { return upperBound; }
double step() const { return step_size; }
};
Calc.cpp
#include "calc.h"
std::ostream& operator<<(std::ostream& os, const pos_inf& inf) {
return os << inf(); // but fails to compile
}
std::ostream& operator<<(std::ostream& os, const neg_inf& inf) {
return os << inf(); // but fails to compile
}
main.cpp
#include "calc.h"
int main() {
neg_inf nif;
pos_inf pif;
limit<double, neg_inf, pos_inf> l(3.4, nif, pif, 2.2);
std::cout << "value dx = " << l.value() << '\n';
std::cout << "lower lim = " << l.lower() << '\n';
std::cout << "upper lim = " << l.upper() << '\n';
std::cout << "step_size = " << l.step() << '\n';
return EXIT_SUCCESS;
}
If this is not what you wanted, I apologize.
After taking the feedback from some who left answers and others who left comments and taking into consideration that the lower and upper bounds may not be of the same type, I had added in the extra template parameter. In this particular implementation it is unavoidable. However by doing so I was able to eliminate the need for inheritance altogether and just made two different structures one for each type. This also simplified my operator<<()s. So my classes now look like this:
calc.h
#pragma once
#include <cmath>
#include <iostream>
#include <limits>
#include <type_traits>
struct neg_inf {
constexpr double operator()() { return -std::numeric_limits<double>::infinity(); }
};
struct pos_inf {
constexpr double operator()() { return std::numeric_limits<double>::infinity(); }
};
template<typename dX, class LowerBound, class UpperBound>
class limit {
dX dx;
LowerBound lowerBound;
UpperBound upperBound;
double step_size;
public:
limit( dX x, LowerBound lower, UpperBound upper, double step = 1 ) :
dx{ x }, lowerBound{ lower }, upperBound { upper }, step_size{ step }
{}
dX value() const { return dx; }
LowerBound lower() const { return lowerBound; }
UpperBound upper() const { return upperBound; }
double step() const { return step_size; }
};
calc.cpp
#include "calc.h"
std::ostream& operator<<(std::ostream& os, const neg_inf& inf) {
// not using the parameter, using constructor and its operator()
// since this is a function object or functor and returns a constexpr
return os << neg_inf()();
}
std::ostream& operator<<(std::ostream& os, const pos_inf& inf) {
// not using the parameter, using constructor and its operator()
// since this is a function object or functor and returns a constexpr
return os << pos_inf()();
}
Now in main, very similar as in my original but with the few modifications:
#include "calc.h"
int main() {
neg_inf nif;
pos_inf pif;
limit<double, neg_inf, pos_inf> l(3.4, nif, pif, 2.2);
std::cout << "value dx = " << l.value() << '\n'
<< "lower lim = " << l.lower() << '\n'
<< "upper lim = " << l.upper() << '\n'
<< "step_size = " << l.step() << '\n';
return EXIT_SUCCESS;
}
And this does work and gives me the output:
value dx = 3.4
lower lim = -inf
upper lim = inf
step_size = 2.2
Note However after thinking about this and getting it to work and comparing it with some of the other answers this does match, user's curiouslyrecurringthoughts answer.

C++ -- How write a function, that return the derivative of a real valued function, not the value of the derivative

This function calculates the value of the Derivation of the Function Foo at X
double Deriv( double(* Foo)(double x), double X )
{
const double mtDx = 1.0e-6;
double x1 = Foo(X+mtDx);
double x0 = Foo(X);
return ( x1 - x0 ) / mtDx;
}
I would like to write a Funktion, which returned not the value of the derivation at X, but a new function which IS the derivation of the function Foo.
xxxx Deriv( double(* Foo)(double x) )
{
return Derivation of Foo;
}
Then it would be possible to write
SecondDeriv = Deriv( Deriv( Foo ))
Is it possible in C++ according to new standard to write such a function ?
I think with old standard it was impossible.
Once you can compute the value of a function at one point, you can use that to implement your general function. Lambda expressions allow you to generate those derived functions easily:
auto MakeDerivative(double (&f)(double)) {
return [=](double x) { return Deriv(f, x); };
}
If you want to be able to use stateful functions, you may need to update your Deriv to be a function template whose first parameter type is a template parameter. This is true in particular if you want to apply MakeDerivative repeatedly (since its return types are stateful closures):
template <typename F>
double Deriv(F f, double x) {
// your code here
}
template <typename F>
auto MakeDerivative(F f) {
return [=](double x) { return Deriv(f, x); };
}
However, you may be interested in techniques like "automatic differentiation" which allow you to express the derivative directly in terms of the definition of the original function, at the cost of working on an enlarged domain (an infinitesimal neighbourhood, essentially).
Here's one way to do it.
#include <iostream>
#include <functional>
std::function<double(double)> Deriv( double(*Foo)(double x) )
{
auto f = [Foo](double x) -> double
{
const double mtDx = 1.0e-6;
double x1 = Foo(x+mtDx);
double x0 = Foo(x);
return ( x1 - x0 ) / mtDx;
};
return f;
}
double Foo(double x)
{
return x*x;
}
double Bar(double x)
{
return x*x*x;
}
int main()
{
std::cout << Deriv(Foo)(10) << std::endl;
std::cout << Deriv(Bar)(10) << std::endl;
}
Output:
20
300
Using generic lambda, implementing a toy derivative is simple. In the following code, derivative is a derivative operator in the math sense. It accepts a function double -> double, produces its derivative double -> double.
#include <iostream>
double delta = 0.001;
auto derivative = [] ( auto foo ) {
return [foo] (double x) {
// the simplest formula for numeric derivative
return (foo(x + delta) - foo(x)) / delta;
};
};
// test
int main() {
auto quar = [] ( double x ) { return x * x; };
auto dev_quar = derivative(quar);
auto dev_dev_quar = derivative(dev_quar);
for ( double s = 0.0; s < 10.0; ++s ) {
std::cout << "(" << quar(s) << "," << dev_quar(s) << "," << dev_dev_quar(s) << ")\n";
}
}

Create a sum of two Array instances

The essence of what I want to do is to take two instances of Vector2D and create a third vector that is to be returned and made into the third instance. The problem I am facing is that I am not entirely sure on how to go ahead in doing so. I have tried to find the syntax for sending in instances, if there is such a one, but I have not managed to find anything useful in any of my books.
#include<iostream>
#include<string>
#include<array>
using namespace std;
class vector2D
{
public:
array<float, 2> get()
{
return xy_coord;
}
void set(float x, float y)
{
xy_coord[0] = x;
xy_coord[1] = y;
}
array<float, 2> vectorAdd(a, b)
{
array<float, 2> c;
for (int i = 0; i < 2; i++)
{
c[i] = a[i] + b[i];
}
return c;
}
private:
array<float, 2> xy_coord;
};
int main()
{
string y;
vector2D a, b, c;
array<float, 2> temp;
a.set(2.0, 3.0);
b.set(4.0, 5.0);
temp = c.vectorAdd(a, b);
c.set(temp[0], temp[1]);
getline(cin, y);
}
The idea is to send in the instances a and b to vectorAdd and sum them up and then set c equal to the returned value (I am sure there is a better way to write the code in the main(), but I am not sure how). In short, what would a and b need to be defined as to make this work, assuming it can work at all.
Maybe you could do something like this instead, so you don't have to pass array around:
#include <iostream>
class Vector2D
{
private:
double _x;
double _y;
public:
Vector2D() = delete;
Vector2D(double x, double y) : _x(x), _y(y) {}
double X() const { return _x; }
double Y() const { return _y; }
Vector2D operator+(Vector2D const &v) const
{
return Vector2D(X() + v.X(), Y() + v.Y());
}
};
int main()
{
Vector2D v1(10.0, 20.0);
Vector2D v2(100.0, 200.0);
Vector2D v3 = v1 + v2;
std::cout << v3.X() << " " << v3.Y();
return 0;
}
Prints:
110 220
Do you need to use array<float, 2>? Have you thought of using pair<float, float>?
A lot (all?) of the operations that you have in your Vector2D class come for free with Pair<>.
Then you just create operator+ as others have suggested.
#include <iostream>
#include <utility>
using namespace std;
using Coord = pair<float, float>;
template <typename L, typename R>
Coord operator+(const L& x, const R& y) { return std::make_pair(x.first + y.first, x.second + y.second); }
int main()
{
Coord a { 5.0f, 6.0f };
Coord b { 7.0f, 9.0f };
Coord c = a + b;
std::cout.precision(5);
std::cout << "c= (" << std::fixed << c.first << ", " << c.second << ")" << std::endl;
return 0;
}