I implemented a conversion for feet to Meters as noted below but I am unable to print out the results in my main. Below is the code generating the error in
Ftr cnum1(2);
Mtr cnum2 = cnum1.toMtr();
std::cout << cnum1.getNum() <<" feet = " << cnum2.getMtrNum() << " meters \n\n";
I’m unable to use the getNum method with cnum2 because getNum is not a method in Mtr. However the results can be accurately displayed in the Ftr.cpp file
#include "Ftr.h"
#include <iostream>
#include <string>
namespace fun::calc
{
Ftr::~Ftr() { }
Ftr::Ftr(double Ftr) noexcept { }
double Ftr::getNum() const noexcept { return m_Num;}
Mtr Ftr::toMtr() const noexcept { return Mtr(m_Num * fInMtr); }
The Ftr header file contains the following:
#ifndef __FTR_H
#define __FTR_H
#include <cstdint>
#include “Mtr.h”
namespace fun::calc
{
class Mtr;
class Ftr
{
double m_Num;
static constexpr double fInMtr = 0.3048;
public:
Ftr() = delete;
explicit Ftr(double Ftr) noexcept;
~Ftr() noexcept;
Ftr(const Ftr &other) = default;
Ftr(Ftr &&other) = default;
double getNum() const noexcept;
Ftr operator+(const Ftr &rhs) const;
Mtr toMtr() const noexcept;
};
}
#endif;
I tried to create a getMtrNum function in the Mtr.cpp as follows:
double Meters:: getMtrNum () const noexcept { return m_mtr;}
I modified main() to use getMtrNum as shown below
Ftr cnum1(2);
Mtr cnum2 = cnum1.toMtr();
std::cout << cnum1.getNum() <<" feet = " << cnum2.getMtrNum() << " meters \n\n";
The results now display 0.0 because n_mtr is initialized to 0.0 in the Mtr.h file
The output produced is :
2 feet = 0 meters
Any suggestions on how to implement this to get the correct results displayed outside of the function definition? Ideally I would like to generate the correct results without having to create getMtrNum. Please provide some guidance on the proper way to get data flowing between the 2 different classes and display the results properly.
If I understood correctly, there are two points you would like to do:
Fix the code so it shows the conversion value
Make the print without creating getMtrNum()
For the second point, if you want to keep your member private, you will need to create a getter/printer function in any case. Probably a bit more elegant if you create an ostream "<<" operator overload. In this way you don't need to use getter function during printing Meters.
Edit: To be more precise getter is still used. Once in the operator overload
std::ostream& operator<<(std::ostream& out, const Meters& m)
{
out << m.Get();
return out;
}
// in main
// std::cout << cnum1.Get() <<" feet = " << cnum2 << " meters \n\n";
A complete working example:
#include <iostream>
class Meters {
public:
Meters(const Meters& m)
:m_Meters(m.m_Meters)
{
}
Meters(double m)
:m_Meters(m)
{
}
double Get() const { return m_Meters; }
private:
double m_Meters{};
};
std::ostream& operator<<(std::ostream& out, const Meters& m)
{
out << m.Get();
return out;
}
class Feet{
public:
Feet(double f)
: m_Feet(f)
{}
static constexpr double fInMtr = 0.3048;
Feet() = default;
Meters ToMeters() const { return Meters(m_Feet * fInMtr); }
double Get() const { return m_Feet; }
private:
double m_Feet{};
};
int main()
{
Feet cnum1(2);
Meters cnum2 = cnum1.ToMeters();
std::cout << cnum1.Get() <<" feet = " << cnum2 << " meters \n\n";
}
I hope, this is what you were looking for.
My question is at the bottom.
I am creating a module for a Mark to encapsulate between 0 and 100.
I have a few operator and conversion overload functions so far:
class Mark {
int mark;
public:
Mark(); //constructor
~Mark(); //deconstructor
Mark(int value); // mark is created using int value that sets the value of mark
void setEmpty(); // mark = 0
bool isValid()const; //checks if mark is valid
//type conversion
operator int() const; // mark casted to an int. result would be value of the mark or zero if mark is invalid
operator double() const; //mark casted to a double for gpa..equivalent of int value
operator char() const; // mark casted to char type...result would be grade latter value of mark
//binary member operator
Mark& operator += (int w); // int is added to the value of mark
Mark& operator = (int i); // mark is set to an integer
};
This is the main program:
This is the output:
HERE IS MY QUESTION
I am trying to add mark to an integer and return that integer and any invalid marks would not add any value to the integer. In the main program, this is the code, its the very last 2 lines.
Mark n(80), k(120);
cout << (val += n) << endl;
cout << (val += k) << endl;
and the output would be
140
140
I am not able to create this without their being errors saying that my += operator from above is ambiguous. So I am thinking that this needs to be a helper function?
Any help on how to do this?
Your implicit casting is weakening your type. It is so weak, that it has now become ambiguous. Since you allow a Mark to be automatically converted into an int, you may as well just use an int and create stand-alone functions that manipulate ints instead of Marks.
If you insist to manipulate Marks, you should create a type that has a smaller interface that enforces your invariants. I don't know what those are, but let's say that a Mark must be an int in [0, 100]. The following type (class) will ensure that you cannot create a Mark with values outside that range. Any accessory functionality is added as a stand-alone function that takes a Mark and manipulates its value with the confidence that such value will never be outside [0,100], because it is impossible for it to be outside the range.
#include <iostream>
#include <stdexcept>
class Mark {
public:
Mark(int value = 0) {
validate(value);
m_value = value;
}
int value() const { return m_value; }
void clear() { m_value = 0; }
// I don't know why you need in-place modifications, but here they are and
// they are exception safe.
Mark& operator+=(const Mark& other) {
int new_value = value() + other.value();
validate(new_value);
m_value = new_value;
return *this;
}
Mark& operator-=(const Mark& other) {
int new_value = value() - other.value();
validate(new_value);
m_value = new_value;
return *this;
}
private:
void validate(int value) const {
// place your own logic here -- the purpose is to ensure that a Mark cannot
// exist unless it is in a valid state.
if (value < 0 || value > 100) {
throw std::runtime_error("value must be in [0, 100]");
}
}
int m_value = 0;
};
double to_double(const Mark& mark) {
// replace with your own logic
return mark.value() / 100.0;
}
char to_char(const Mark& mark) {
// replace with your own logic
if (mark.value() > 0 && mark.value() < 50) {
return 'D';
} else if (mark.value() >= 50 && mark.value() <= 100) {
return 'A';
} else {
return 'X';
}
}
std::ostream& operator<<(std::ostream& os, const Mark& m) {
// replace with your own logic
return os << "Mark(" << m.value() << ") / " << to_double(m) << " / "
<< to_char(m);
}
int main() {
Mark m;
Mark n(25);
Mark k(100);
// Mark p(-10); // uncommented will throw exception
std::cout << m << "\n"
<< n << "\n"
<< k << "\n"
// << p << "\n" // uncommented will throw exception
;
}
Sample output:
$ clang++ example.cpp -std=c++2a
$ ./a.out
Mark(0) / 0 / X
Mark(25) / 0.25 / D
Mark(100) / 1 / A
My data file looks like below:
x y z
0.068472 -0.024941 0.028884
.... .... ....
continued, there are more than 100 points.
I want to find the closest point among all the data points to point 1 (in
this case (0.068472,-0.024941, 0.028884). My code to read the file is below, what function should I add to find the closest point to point 1? Should I use the minimum function to find the minimum distance between point 1 and the other? But I am not sure how to write this in code.
// Program to read an input file
#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
using namespace std;
int main() {
const int MAXI = 1000;
double x, y, z, xcoordinates[MAXI], ycoordinates[MAXI], zcoordinates[MAXI];
int i, count;
ifstream inFile("input-week6-ad-q4-2.txt"); // ifstream function to read the file
string line, c; // To read the characters
if (inFile.is_open()) {
getline(inFile, line); // To read the header of the input file then discard it
getline(inFile, line);
i = 0;
count = 0;
while (inFile >> x >> y >> z) {
xcoordinates[count] = x;
ycoordinates[count] = y;
zcoordinates[count] = z;
count = count + 1;
}
for (i = 0; i < count; i++) {
cout << xcoordinates[i] << " " << ycoordinates[i] << " " << zcoordinates[i] << "\n";
}
inFile.close();
} else {
cout << "The file could not be opened." << "\n"; // To check for any error
}
system("pause");
return 0;
}
The comments offer the right direction. If you are going to write your minimum distance finder is C++, you should start with a simple 2d point class and then derive a class to handle 3d points from that class by adding a 3rd coordinate. If you are simply going to use separate x, y, z coordinate and three separate arrays of double -- you might as well write the program in C.
Writing a base class for a 2d point isn't difficult at all. The only thing you need to be mindful of in order to then derive a 3d class from it is to declare your coordinate members as protected: so that all protected members of the 2d point class are available as protected member in the 3d class (class members are private by default and private members of the base are never accessible unless friended)
So what would a minimum 2d point base class look like? Well you would need x, y coordinates, you would need a default constructor to set x and y to 0.0 when the class is constructed, a constructor to takexandyvalues, and then a couple of accessor functions to get thexandy` values for use in your distance function.
A minimum 2d point class could be:
/* 2D Cartesian Coordinate Point */
class point2_t {
protected: /* allows derived class access to x, y when inherited */
double x, y; /* private members would not be accessible */
public:
point2_t () { x = 0.0, y = 0.0; } /* constructors */
point2_t (const double a, const double b) : x{a}, y{b} { }
const double& getx () const { return x; } /* access functions */
const double& gety () const { return y; }
double dist (const point2_t& p) { /* distance function */
return sqrt ((x-p.getx()) * (x-p.getx()) +
(y-p.gety()) * (y-p.gety()));
}
};
That will allow you to initialize a 2d point with values, get the values currently set and then calculate the distance from some other 2d point. While that will work great, it would still require reading the x and y values from the file and then creating a point by passing the coordinates to the constructor. (your could also write a setx(double x) and corresponding sety() to allow you to change the x, y values)
It would be really nice to be able to just cin >> point; and have it set the x, y values automatically and to be able to cout << point; to output the coordinates. You can do so by overloading the << and >> operators. That makes it really convenient to read and output the coordinate data. To do so you can add the following as member functions:
/* overload output and input operators */
friend std::ostream& operator << (std::ostream& os, const point2_t& p) {
os << "(" << p.x << ", " << p.y << ")";
return os;
}
friend std::istream& operator >> (std::istream& is, point2_t& p) {
is >> p.x >> p.y;
return is;
}
Once you have your 2d point class written, all you need to do is derive a 3d point class from it and add a z coordinate and the corresponding functions to handle all three coordinates instead of two. The basic form to derive a class from a base class including the protected members of the base class is:
class derived : public base {
/* additions */
};
A simple derivation from your 2d point class for a 3d point class (including the overloading << and >> operators) could be:
/* 3D Cartesian Coordinate Point derived from 2D point class */
class point_t: public point2_t {
protected:
double z; /* add z coordinate */
public:
point_t () { point2_t (0.0, 0.0); z = 0.0; }; /* default construct */
/* construct with initializer list */
point_t (const double a, const double b, const double c) :
point2_t (a, b), z{c} {}
const double& getz () const { return z; } /* add getz accessor */
double dist (const point_t& p) { /* extend distance */
return sqrt ((x-p.getx()) * (x-p.getx()) +
(y-p.gety()) * (y-p.gety()) +
(z-p.getz()) * (z-p.getz()));
}
/* extend operators */
friend std::ostream& operator << (std::ostream& os, const point_t& p) {
os << "(" << p.x << ", " << p.y << ", " << p.z << ")";
return os;
}
friend std::istream& operator >> (std::istream& is, point_t& p) {
is >> p.x >> p.y >> p.z;
return is;
}
};
Now you have a 3d point class that can calculate the distance between points. All that remains is creating an instance of the class for your 1st point, and a second temporary instance to read additional points from your file allowing you to compute the distance between the two. (a 3rd instance is handy if you want to save the coordinates for the closest point)
The only caveat with your data file is you need to discard the first line containing the x y z heading. While you can read a the line into a string with getline and simply ignore it, C++ also provides a stream function .ignore() which allows you to ignore up to the maximum number of readable characters until a delimiter is reached (the newline in this case). Simply include the limits header and you can then use:
std::ifstream f (argv[1]); /* open file stream */
...
/* discard 1st line in file */
f.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
(either way works)
There is no need to read all the points in the file into a container to process later just to find the minimum of the distance between the first point and the rest. All you need to do is store the first point (p1 below) and then compute the distance between it and the remaining points, saving the minimum distance (distmin below) found for each subsequent comparison. (you can also save the coordinate of the closest point if you like)
Putting that together in a short main() could look like:
int main (int argc, char **argv) {
if (argc < 2) { /* validate argument available for filename */
std::cerr << "error: insufficient input.\n";
return 1;
}
std::ifstream f (argv[1]); /* open file stream */
point_t p1, min, tmp; /* 1st, mininum & temporary points */
/* initialize minimum distance to maximum allowable */
double distmin = std::numeric_limits<double>::max();
/* discard 1st line in file */
f.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
if (!(f >> p1)) { /* read 1st point */
std::cerr << "error: failed read of p1\n";
return 1;
}
while (f >> tmp) { /* read remaining points */
double dist = tmp.dist (p1); /* get distance from p1 */
if (dist < distmin) { /* check less than distmin? */
distmin = dist; /* set new distmin */
min = tmp; /* set new closest point */
}
}
/* output results */
std::cout << "\nclosest point to " << p1 << "\n\n" << min <<
"\n\ndistance: " << distmin << '\n';
}
The complete example would then be:
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cmath>
#include <limits>
/* 2D Cartesian Coordinate Point */
class point2_t {
protected: /* allows derived class access to x, y when inherited */
double x, y; /* private members would not be accessible */
public:
point2_t () { x = 0.0, y = 0.0; } /* constructors */
point2_t (const double a, const double b) : x{a}, y{b} { }
const double& getx () const { return x; } /* access functions */
const double& gety () const { return y; }
double dist (const point2_t& p) { /* distance function */
return sqrt ((x-p.getx()) * (x-p.getx()) +
(y-p.gety()) * (y-p.gety()));
}
/* overload output and input operators */
friend std::ostream& operator << (std::ostream& os, const point2_t& p) {
os << "(" << p.x << ", " << p.y << ")";
return os;
}
friend std::istream& operator >> (std::istream& is, point2_t& p) {
is >> p.x >> p.y;
return is;
}
};
/* 3D Cartesian Coordinate Point derived from 2D point class */
class point_t: public point2_t {
protected:
double z; /* add z coordinate */
public:
point_t () { point2_t (0.0, 0.0); z = 0.0; }; /* default construct */
/* construct with initializer list */
point_t (const double a, const double b, const double c) :
point2_t (a, b), z{c} {}
const double& getz () const { return z; } /* add getz accessor */
double dist (const point_t& p) { /* extend distance */
return sqrt ((x-p.getx()) * (x-p.getx()) +
(y-p.gety()) * (y-p.gety()) +
(z-p.getz()) * (z-p.getz()));
}
/* extend operators */
friend std::ostream& operator << (std::ostream& os, const point_t& p) {
os << "(" << p.x << ", " << p.y << ", " << p.z << ")";
return os;
}
friend std::istream& operator >> (std::istream& is, point_t& p) {
is >> p.x >> p.y >> p.z;
return is;
}
};
int main (int argc, char **argv) {
if (argc < 2) { /* validate argument available for filename */
std::cerr << "error: insufficient input.\n";
return 1;
}
std::ifstream f (argv[1]); /* open file stream */
point_t p1, min, tmp; /* 1st, mininum & temporary points */
/* initialize minimum distance to maximum allowable */
double distmin = std::numeric_limits<double>::max();
/* discard 1st line in file */
f.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
if (!(f >> p1)) { /* read 1st point */
std::cerr << "error: failed read of p1\n";
return 1;
}
while (f >> tmp) { /* read remaining points */
double dist = tmp.dist (p1); /* get distance from p1 */
if (dist < distmin) { /* check less than distmin? */
distmin = dist; /* set new distmin */
min = tmp; /* set new closest point */
}
}
/* output results */
std::cout << "\nclosest point to " << p1 << "\n\n" << min <<
"\n\ndistance: " << distmin << '\n';
}
Example Input File
Generating a few additional random points in the same range as your values would give you a data file with 10 total points to use to validate the program, e.g.
$ cat dat/3dpoints-10.txt
x y z
0.068472 -0.024941 0.028884
-0.023238 0.028574 -0.021372
0.015325 -0.086100 0.011980
-0.028137 -0.025350 0.021614
-0.013860 0.015710 -0.022659
0.026026 -0.093600 0.019175
0.010445 -0.098790 0.023332
-0.021594 0.017428 -0.025986
0.021800 -0.027678 0.017078
-0.016704 0.017951 0.011059
Example Use/Output
Running the program will then locate the closest point to your first point (p1) providing the following answer:
$ ./bin/point_distmin dat/3dpoints-10.txt
closest point to (0.068472, -0.024941, 0.028884)
(0.0218, -0.027678, 0.017078)
distance: 0.0482198
Look things over and let me know if you have questions. cpprefernce.com is one of the best references (aside from the standard itself). Keep that bookmark handy and take some time to get to know the language and the site.
This answer heavily builds on David C. Rankin's. The main() is pretty much copy-pasted with two extra checks, explicit stream closing and some style changes. The chief difference is the way points are stored and thus, treated. No inheritance here. And it's only POD struct anyway.
Data, data, data. You think about the task in terms of points, so you should have a datatype to neatly hold coordinates together as one point:
struct Point3d {
double x, y, z;
};
To cooperate fluently with C++ i/o streams, let's overload the >> and << operators:
std::ostream& operator << (std::ostream& os, const Point3d& p) {
os << "(" << p.x << ", " << p.y << ", " << p.z << ")";
return os;
}
std::istream& operator >> (std::istream& is, Point3d& p) {
is >> p.x >> p.y >> p.z;
return is;
}
Finally, we need to compute the distance between two points. Metrics are symmetric by logic and also by definition, so let us reflect it in code and define a simple function to compute Euclidean distance:
double distance(const Point3d &a, const Point3d &b) {
auto squared = std::pow(a.x-b.x, 2) +
std::pow(a.y-b.y, 2) +
std::pow(a.z-b.z, 2);
return sqrt(squared);
}
Then the whole program is:
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cmath>
#include <limits>
struct Point3d {
double x, y, z;
};
std::ostream& operator << (std::ostream& os, const Point3d& p) {
os << "(" << p.x << ", " << p.y << ", " << p.z << ")";
return os;
}
std::istream& operator >> (std::istream& is, Point3d& p) {
is >> p.x >> p.y >> p.z;
return is;
}
double distance(const Point3d &a, const Point3d &b) {
auto squared = std::pow(a.x-b.x, 2) +
std::pow(a.y-b.y, 2) +
std::pow(a.z-b.z, 2);
return sqrt(squared);
}
int main(int argc, char **argv) {
if (argc != 2) {
std::cerr << "Exactly one argument expected, got " << argc << "\n";
return 1;
}
std::ifstream f(argv[1]);
if (!f.is_open()) {
std::cerr << "error: failed to open '" << argv[1] << "'\n";
return 1;
}
// discard the header line
f.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
Point3d first_pt;
if (!(f >> first_pt)) { // read the first point
std::cerr << "error: failed read of the first point\n";
return 1;
}
bool other_points = false;
double dist_min = std::numeric_limits<double>::max();
Point3d closest, current;
while (f >> current) { // loop through the other points
other_points = true;
double dist = distance(first_pt, current);
if (dist < dist_min) {
dist_min = dist;
closest = current;
}
}
f.close();
if (other_points) {
std::cout << "closest point to " << first_pt <<
" is " << closest << " [distance: " << dist_min << "]\n";
} else {
std::cout << "There was only one point in the file\n";
}
}
You can calculate the Euclidean distances of two points in 3 dimensions (point 1 vs the other points), then compare them to find the closest point. The formula could be found on Wiki: https://en.wikipedia.org/wiki/Euclidean_distance
In an interview I was asked to create two classes. The first abstract class is called Number, which supports one operation “+”. And the other one fraction which implements the "Number" abstract class.
Further: For a Fraction once added, it needs to be displayed in its original form. That is, 2/4 has to be displayed as “2/4”, not “1/2” or “0.5”.
No Other detail was provided to me.
Below is what I had tried (Incomplete).
My main.cpp
#include <iostream>
#include "Fraction.h"
using namespace std;
int main()
{
Fraction sumFraction;
Fraction n11(1,2);
Fraction n21(1,2);
cout << n11.getValuenum() << "/";
cout << n11.getValueden() << endl;
cout << n21.getValuenum() << "/";
cout << n21.getValueden() << endl;
sumFraction = n11 + n21;
cout << sumFraction.getValuenum() << endl;
cout << sumFraction.getValueden() << endl;
return 0;
}
My Numbers.h // ABSTRACT CLASS
#pragma once
template<class T>
class Number
{
virtual T& operator= (const T &) = 0; // first parameter is implicitly passed
virtual const T operator+ (const T &) = 0;
virtual void display() = 0;
};
My Fraction.cpp
#include "Fraction.h"
int Fraction::getValuenum()
{
return this->a1;
}
int Fraction::getValueden()
{
return this->a2;
}
Fraction::Fraction()
{
a1 = 0;
a2 = 0;
}
Fraction::Fraction(int num, int den)
{
a1 = num;
a2 = den;
}
void Fraction::display()
{
// will display the number in its original form
}
Fraction& Fraction::operator=(const Fraction &num)
{
a1 = num.a1;
a2 = num.a2;
return *this;
}
const Fraction Fraction::operator+(const Fraction &numberTwo)
{
Fraction n1;
n1.a1 = this->a1*numberTwo.a2 + this->a2*numberTwo.a1;
n1.a2 = this->a2*numberTwo.a2;
return n1;
}
My Fraction.h
#pragma once
#include "Number.h"
class Fraction : public Number<Fraction>
{
private:
int a1;
int a2;
public:
void display();
Fraction();
Fraction(int num, int den);
int getValuenum();
int getValueden();
Fraction& operator= (const Fraction &); // first parameter is implicitly passed
const Fraction operator+ (const Fraction &); // first parameter is implicitly passed
};
Below are my question:
Do I really need to pass numerator and denominator separately from my Main function for each fraction. Currently, I am passing it as separately to keep track of numerator and denominator which might be helpful while adding and returning the result in terms for fraction.
With my operator + logic if I add 1/4+1/4 I get 8/16, what is expected is I guess 2/4 which we get if we add normally. So how to add using numerator and denominator and to keep the fraction in such a way, so that if output is 2/4 then 2/4 and not 1/2 or 0.5.
Please help me.
Some remarks:
you should not allow the denominator to be 0 because it gives an inexistent number (infinity or undeterminated)
you should definitely not initialize the denominator to 0 for same reason (1 seems a more reasonable value)
the correct (mathematical) addition of fractions is (*):
a/b + c/d = (ad +bc)/bd
Instead of (or in addition to) the display method, I would advise you to write a ostream& operator << (ostream&, const Fraction&) overload. That would allow you to just write in you main
std::cout << n11 << " + " << n21 << " = " << sumFraction << std::endl;
I did not really understand you first question, but I would add a conversion from an int:
Fraction(int n): a1(n), a2(1) {};
to allow to write directly Fraction(1, 2) + 1 or Fraction(1) + Fraction(1/2) (the first element of the addition must be a Fraction)
(*) this is the simple and general way. You could also use the least common multiple to get cleaner results:
den = lcm(b,d)
a/b + c/d = (a * den/b) + c * den/d) / den
That way you would get 1/4 + 2/4 = 3/4 instead of 12/16
But computing the LCM is far beyond this answer...
I'm have a bit problem with operator overloading. I have two classes.
#include <iostream>
using namespace std;
class Meter; //Forward declaration
class Inch{
private:
double inches;
public:
Inch() : inches(0) {}
Inch(double i) { inches=i; }
friend Inch operator+ (const Meter& m, const Inch& i);
void out(){ cout << "Inch:" << inches << "\n"; }
double getInches() const { return inches; }
};
and
class Meter{
private:
double meter;
public:
Meter() : meter(0) {}
Meter(double m) { meter=m; }
Meter operator+ (const Inch& i) { return Meter(meter + i.getInches() * 0.0254); }
void out(){ cout << "Meter:" << meter; }
double getMeter() const { return meter; }
};
Inch operator+ (const Meter& m, const Inch& i)
{ return Inch(m.getMeter()/0.0254 + i.getInches()); }
In main I have one of each of these classes. I need to add them together with the order : m + i; So m must be the first object. In order to do that, I used friend function in order to use two objects as a parameter.
Inch i(6.4), resultInch;
Meter m(14), resultMeter;
i.out();
m.out();
resultMeter = m + i;
resultMeter.out();
resultInch = m + i;
resultInch.out();
With the above, resultMeter holds the correct value, but when I put resultInch compiler gives the "error no match for bla bla bla".
What am I missing?
The problem is that both these two operators are overloads for the exact same + in code. You can either use one or another, but not both in the same program.
Inch operator+ (const Meter& m, const Inch& i);
class Meter{
Meter operator+ (const Inch& i);
};
Consider what would happen if you had one Meter m; and Inch i; and you try to add them with m + i, which operator implementation should be called?
C++ cannot overload on return value. So when you want to be able to say:
meters = meters + inches;
and
inches = meters + inches;
both meters + inches are the same function. I second the recommendation to write one length class with a units attribute and conversion functions. But lacking that, I recommend you write conversion operators between your two length classes. Then only one addition function is needed (you should still write two: meters + meters and inches + inches) and the types can be converted back and forth.
Remove operator+ from both classes. Create proxy class which will be used as the result of addition:
class ProxyMeterInch
{
private:
double op1, op2;
public:
friend ProxyMeterInch operator+(Meter m, Inch i)
{
ProxyMeterInch r;
r.op1 = m.getMeter();
r.op2 = i.getInch() * 0.0254; // I tend to keep it in meters as I am European
return(r);
}
operator Meter() const
{
return(op1 + op2);
}
operator Inch() const
{
return((op1 + op2) / 0.0254);
}
};
You get the idea. Depending on the type you are trying to assign to correct conversion operator will be selected.
Ok, so I assume it's
Inch resultInch = m + i; // not Meter resultInch (...)
It is equivalent to:
Inch resultInch = (Meter)m.operator+(i);
and you have no way of converting between Meter and Inch.
Try changing it to Inch resultInch = i + m;.