I was studying C++, and when I made a little program to learn more about Operator Overloading the program gives an erro in the main function where I wrote "Ponto p1(1,5), p2(3,4), Soma;". Can anyone explain me how to use Operator Overloagin correctly? Thank you.
PS: The program is in Portugueses, my native language, but I think that it will not be a problem to find my erro.
#include <iostream>
using namespace std;
class Ponto
{
private:
int x,y;
public:
Ponto(int a, int b)
{
x = a;
y = b;
}
Ponto operator+(Ponto p);
};
Ponto Ponto::operator+(Ponto p)
{
int a, b;
a = x + p.x;
b = y + p.y;
return Ponto(a, b);
}
int main(void)
{
Ponto p1(1,5), p2(3,4), Soma;
Soma = p1.operator+(p2);
return 0;
}
You don't have a default constructor so when it tries to construct Soma you get an error.
Once you provide your own constructor the default one provided by the compiler is no longer generated. You either have to make your own or add default values to the parameters on the constructor that takes parameters.
You should init Ponto Some in place with some value: Ponto Some = p1 + p2;
Also you should pass "constant reference" - reference to const object: const Ponto &name into the operator+.
So, fixed code:
#include <iostream>
using namespace std;
class Ponto {
int x, y;
public:
Ponto(int, int);
Ponto operator+(const Ponto&);
};
Ponto::Ponto(int a, int b) : x(a), y(b) {}; // Use 'initializer list'
Ponto Ponto::operator+(const Ponto &other) {
// Not need to do calculations explicitly
return Ponto(x+other.x, y+other.y);
}
int main() {
Ponto p1(1, 5), p2(3, 4);
// Not need to call operator+ explicitly - it's compiler's work
Ponto Soma = p1 + p2;
return 0;
}
Related
struct P {
int x, y;
friend P operator-(P u, P v) { return {u.x - v.x, u.y - v.y}; }
friend int cross(P u, P v) { return u.x * v.y - u.y * v.x; }
int cross(P u, P v) const { return cross(u - *this, v - *this); }
};
The method is an infinite loop (it will call itself instead of the friend).
Is there any way to get around this issue without changing the interface (the names)?
It is possible with a declaration inside the member function:
#include <stdio.h>
struct Foo {
friend int add(int a, int b) {
return a + b;
}
int add(int a, int b) const {
int add(int, int); // function declaration
return add(a, b); // call that declared function
}
};
int main() {
Foo foo;
printf("%d", foo.add(1, 2)); // prints 3
}
Demo
You can't have two member functions with the same name and the same signature in a struct (or class).
One solution is to move the friend function out of the struct, so that it can be referred to with a global namespace specifier ::
#include <iostream>
int cross(int i) { return 42; }
struct P {
friend int cross(int i);
int cross(int i) const { return ::cross(i - 1); }
};
int main() {
P p = {};
std::cout << p.cross(7) << std::endl;
}
The original code produced two warnings, very descriptive:
1 > 1.cpp(6, 25) : warning C4514 : 'cross' : unreferenced inline function has been removed
1 > 1.cpp(7) : warning C4717 : 'P::cross' : recursive on all control paths, function will cause runtime stack overflow
Re: without changing the interface (the names) - you could simply rename your friend function and even make it private; it is not a part of the interface.
Ayxan Haqverdili's answer seems to be cleanest possible, and abides by the ISO. However, pre-gcc 11.0 and pre-clang 8.0 appear to have bugs that cause this to fail.
Luckily in this case there's an alternative that uses argument-dependent lookup:
#include <iostream>
class Foo
{
friend int Bar (Foo)
{
return 13;
}
friend int RedirectToBar (Foo);
public:
int Bar (Foo)
{
return RedirectToBar(Foo());
}
};
int RedirectToBar (Foo)
{
return Bar(Foo());
}
int main ()
{
std::cout << Foo().Bar(Foo()) << std::endl;
}
Live demo
Keep in mind that this only works because some of the arguments to the function are an associated class.
If that's not the case and you really want to keep this design and really need compatibility with older compilers, then we can add in a dummy associated class without breaking the interface by adding it as a default parameter:
#include <iostream>
int RedirectToBar ();
class Foo
{
struct Key {};
friend int Bar (Key = Key())
{
return 13;
}
friend int RedirectToBar ();
public:
int Bar ()
{
return RedirectToBar();
}
};
int RedirectToBar ()
{
return Bar(Foo::Key());
}
int main ()
{
std::cout << Foo().Bar() << std::endl;
}
Live demo
However, it's important to add that all of this is a big code smell. Although I don't know the real-world problem of the OP, this seems like a terrible hack to get around bad design choices.
I ended up using this solution similar to Peter's and Yksisarvinen's:
struct P {
int x, y;
friend P operator-(P u, P v) { return P{u.x - v.x, u.y - v.y}; }
friend int cross(P u, P v);
int cross(P u, P v) const;
};
int cross(P u, P v) { return u.x * v.y - u.y * v.x; }
int P::cross(P u, P v) const { return ::cross(u - *this, v - *this); }
Not quite sure yet why the compiler doesn't find ::cross if I write it inside of P.
Note, there is one potential drawback: we have to specify the return type of both functions (can't have it deduced with auto), but this was not needed in this case.
First, I am a beginner in C++. Second, I'm sorry of this post turns out to be too long. I have a few classes that make use of each other, similar to this picture (a quick sketch):
And this is a quick sketch of a usable code. The formulas are bogus, but the functionality is close to the real problem. I omitted making source files for simplicity. The #includes are as they were after the last compile that got me the fewest errors...
"y.h"
#pragma once
#include "a.h"
#include "b.h"
class X;
class A;
class B;
class Y
{
private:
double m_y;
public:
Y(double b, double c):
{
if (c)
m_y = b*b;
else
m_y = sqrt(b);
if (b<0)
{
A::setP(m_y);
A::setQ(m_y + 1);
A::setR(m_y - 1);
}
else
{
B::setP(m_y);
B::setQ(m_y + 1);
B::setR(m_y - 1);
}
}
"a.h"
#pragma once
#include "x.h"
class X;
class A : virtual public X
{
private:
double m_p, m_q, m_r;
public:
A(double a, double b): m_p {a*a}
{
m_q = m_p + 0.5 * b;
m_r = m_q - m_p;
}
void setP(double p) { m_p = p; }
void setQ(double q) { m_q = q; }
void setR(double r) { m_r = r; }
double getP() { return m_p; }
double getQ() { return m_q; }
double getR() { return m_r; }
};
"b.h"
#pragma once
#include "x.h"
class X;
class B : virtual public X
{
private:
double m_p, m_q, m_r;
public:
B(double a, double b): m_p {a + a}
{
m_q = m_p*m_p;
m_r = b + m_q;
}
void setP(double p) { m_p = p; }
void setQ(double q) { m_q = q; }
void setR(double r) { m_r = r; }
double getP() { return m_p; }
double getQ() { return m_q; }
double getR() { return m_r; }
};
"x.h"
//#include "a.h"
class A;
class B;
class X
{
private:
double m_x1, m_x2;
public:
X(double a, double b, double c, int d): m_x1 {2*a}
{
double p, q, r;
switch (d)
{
case 1:
p = A::getP();
q = A::getQ();
r = A::getR();
m_x2 = p * b + q * c - r;
break;
case 2:
p = B::getP();
q = B::getQ();
r = B::getR();
m_x2 = (p - q) * b + r / c;
break;
}
}
double getX1() { return m_x1; }
double getX2() { return m_x2; }
};
"main.cpp"
#include "x.h"
#include <iostream>
int main()
{
X test {3.14, 0.618, 1.618, 1};
std::cout << test.getX1() << '\t' << test.getX2() << '\n';
return 0;
}
My problem is with the necessary includes (assume each class has a header and source file). For now, let's consider only class A in there. main.cpp only has #include x.h. To avoid repeating the code with all combinations, I'll try ennumerating what I did, so far:
#include a.h in class X, then #include y.h in class A, class Y has no #include, no forward declarations. The compiler complains about expected class name before { in both Y and A.
add forward declarations to the above => invalid use of incomplete type "class ..." in both Y and A.
do it backwards with #include a.h in class Y, then #include x.h in class A, class X has no #include, with forward declarations => incomplete type A used in nested name spacifier in class X, pointing at X(): { int x {A::funcA()} }.
as above and no forward declarations means errors everywhere.
Searches on the net said this happens because of cyclic dependencies, but how can that be since I am only including the previous or the next, never both? There were answers saying that using #pragma once instead of the usual may resolve the problems, I tried, it's the same incomplete type.... For reference only, I also tried looking at a few source codes (wxMaxima, audacious) to see how they did it, and it seems they used my first approach.
At this point, I am very confused. If the above can be used for an answer, can someone please give me some directions on how to properly use the #includes here? If not, please leave a comment and I'll delete this, if needed.
I feel like this question must have been asked before but I couldn't find an answer from poking around on google. If it has please direct me to a link and I will remove this post.
Consider this minimal example that represents a larger problem I have. Say I created a simple "Point" and "Printer" class like so:
class Point {
public:
double x, y;
Point() {x = y = 0;}
Point(double x, double y) {
this->x = x; this->y = y;
}
};
template<typename T>
class Printer {
public:
T* mData;
int mSize;
// Constructor
Printer(std::vector<T> &input) {
mData = &input[0];
mSize = input.size();
}
// Simple Print function
void Print() {
printf(" - Showing %d items\n", mSize);
for (int i = 0; i < mSize; i++) {
const T &item = mData[i];
printf(" - Item %d: (%lf, %lf)\n", i, item.x, item.y);
}
}
};
I could use the printer class like this:
std::vector<Point> points; // fill the vector, and then...
Printer<Point> pointsPrinter(points); pointsPrinter.Print();
Now say someone else comes along and wants to use the Printer class with there own "Point" class declared like so:
class Pnt {
public:
double mX, mY;
// other stuff
};
If they try to do this:
vector<Pnt> pnts; // Fill the pnts, and then...
Printer<Pnt> pntsPrinter(pnts);
pntsPrinter.Print(); // COMPILE ERROR HERE!
Obviously this will fail because Pnt has no x or y members. Does there exist a way I can rewrite the Printer class to work with all generic user types? What I DONT want to do is copy a Pnt vector into a Points vector.
EDIT:
The only way I can think to make this work would be to pass in functions pointers. Something like this:
template<typename T>
class Printer {
public:
T* mData;
int mSize;
double* (*mXFunc) (T*);
double* (*mYFunc) (T*);
Printer(std::vector<T> &input,
double* (*xFunc) (T*),
double* (*yFunc) (T*))
{
mData = &input[0];
mSize = input.size();
mXFunc = xFunc;
mYFunc = yFunc;
}
void Print() {
printf(" - Showing %d items\n", mSize);
for (int i = 0; i < mSize; i++) {
T &item = mData[i];
printf(" - Item %d: (%lf, %lf)\n", i, *mXFunc(&item), *mYFunc(&item));
}
}
};
// Could then use it like so
inline double* getXPointVal(Point *point) {return &point->x;}
inline double* getYPointVal(Point *point) {return &point->y;}
inline double* getXPntVal(Pnt *point) {return &point->mX;}
inline double* getYPntVal(Pnt *point) {return &point->mY;}
Printer<Pnt> pntPrinter(pnts, getXPntVal, getYPntVal);
Printer<Point> pointsPrinter(points, getXPointVal, getYPointVal);
pntPrinter.Print();
pointsPrinter.Print();
The problem with this is that it looks ugly and also possibly introduces the function call overhead. But I guess the function call overhead would get compiled away? I was hoping a more elegant solution existed...
If you choose cout instead of printf to write your output, you can allow all printable types to define an overload for the << operator and use that generically inside Printer::print(). An overload could look like this:
std::ostream& operator<<(std::ostream &out, Point& p){
out << "Point(" << p.x << ", " << p.y << ")";
return out;
}
On a side note, I advise against storing a pointer to a vector's internal storage and size member. If the vector needs to reallocate, your pointer will be left dangling and invalid. Instead, you should pass the vector temporarily as a reference or keep a const reference.
You could define free (non-member) functions for each Point class you want to use. The advantage of this is that free functions can be defined later, without making changes to existing classes.
Example:
namespace A {
class Point {
public:
Point (int x, int y) : x_(x), y_(y) {}
int getX () const { return x_; }
int getY () const { return y_; }
private:
int x_, y_;
};
// in addition, we provide free functions
int getX (Point const & p) { return p.getX(); }
int getY (Point const & p) { return p.getY(); }
}
namespace B {
class Pnt {
public:
Pnt (int x, int y) : x_(x), y_(y) {}
int get_x () const { return x_; }
int get_y () const { return y_; }
private:
int x_, y_;
};
// Pnt does not have free functions, and suppose we
// do not want to add anything in namespace B
}
namespace PointHelpers {
// free functions for Pnt
int getX (Pnt const & p) { return p.get_x (); }
int getY (Pnt const & p) { return p.get_y (); }
}
// now we can write
template <class PointTy>
void printPoint (PointTy const & p) {
using PointHelpers::getX;
using PointHelpers::getY;
std::cout << getX (p) << "/" << getY (p) << std::endl;
}
A::Point p1 (2,3);
B::Pnt p2 (4,5);
printPoint (p1);
printPoint (p2);
If the free functions live in the same namespace as the corresponding class, they will be found by argument-dependent name lookup. If you do not want to add anything in that namespace, create a helper namespace and add the free functions there. Then bring them into scope by using declarations.
This approach is similar to what the STL does for begin and end, for instance.
Don't expect from the templates to know which members of given class/structure corresponds to your x and y...
If you want to create generic solution you could tell your printer function how to interpret given object as your Point class using e.g. lambda expression (c++11 solution):
#include <iostream>
class Point {
public:
double x, y;
Point() {x = y = 0;}
Point(double x, double y) {
this->x = x; this->y = y;
}
};
class Pnt {
public:
double mX, mY;
// other stuff
};
template <class P, class L>
void Print(const P &p, L l) {
Print(l(p));
}
void Print(const Point &p) {
std::cout << p.x << ", " << p.y << std::endl;
}
int main() {
Print(Point(1, 2));
Print(Pnt{4, 5}, [](const Pnt &p) -> Point {return Point(p.mX, p.mY);});
}
Would that be possible to help me to pass a functor, such as :
struct BFunc
{
double operator()(const double x, const double y, const double z){
return 0.1;
}
};
to a the constructor of a class:
class foo
{
int n;
public:
foo();
foo(int nn, &bfunc):n(nn),f(func()){
}
double getResult(double x){
return f(x);
}
}
Thanks,
Thank you all for your quick response. I solved it, by declaring a variable of type functor as bellow. But I was wondering if it is possible to do it without that. The point is I wanted to create a class, which I pass a function as boundary condition and a range to it, so it creates a 2D or 3D matrix of coordinates which gives zero to all points inside and zero to all points outside. I wanted to make it as general as possible. Eventually I ended up to follow following method.
using namespace std;
struct functor {
int a=11;
int operator () (int x) const {
cout << a << endl;
return 2*x;
}
};
class myclass {
int y=0;
functor af;// ** I did not wanted to have this line and make it generic ** //
public:
template <typename F> myclass(const F & f):af(f){
//af=f;//auto af(f);
y=f(5);
cout<<"y is"<<y<<endl;
int z=af(5);
cout<<"z is"<<z<<endl;
cout<<" why "<<typeid(af).name()<<endl;
}
int getFuncX(int x){
int y=af(x);
return y;
}
};
int main(int argc, char **argv) {
functor f = {5};
myclass c(f);
cout<<" See What happens: "<<c.getFuncX(71)<<endl;
return 0;
}
Sorry if it is messy! As you guessed I am a beginner.
Thanks
I have the following program:
#include <iostream>
using namespace std;
class N {
public:
float x;
N(){ x = 3.0; }
N(float y){ x = y; }
N &operator=(float f){ return *new N(f); }
};
int main(){
N a;
a = 2.0;
cout << a.x;
return 0;
}
I am expecting for the result to be 2 (because of definition of operator=), but instead it gives me 3 (like there is no line a = 2.0). Can someone, please, explain me why is this happening, what is wrong with definition of 'operator='? Thank you...
Your copy assignment operator should be setting the value of x, then returning a reference to *this, like so:
N &operator =(float f) { x = f; return *this; }
Instead, your copy assignment operator is constructing a new instance of N on the heap, and returning a reference to that.
You shouldn't use new, C++ isn't java.
N& operator=(float f)
{
x = f;
return *this;
}
Try this.