I the next simple constructor:
Vector(double x=0, double y=0) : x(x), y(y) {}
void operator+=(const Vector& other) {
this->x += other.x;
this->y += other.y;
}
But when I call it like this
Vector b();
Vector a(1,1);
and try to do a += b;
compiler gives me a lot of errors saying that no operators exist. However when I do like this:
Vector b(0,0);
or
Vector b(0);
everything works(((
Vector b(); doesn't create an object. It declares a function.
Vector b;
Vector a(1,1);
should work.
Related
now i am stumbling with c++ code problem.
i made a simple structure 'Vector3' in that i defined the operator+.
and when i use that operator inside const function, it show a red line.
struct Vector3 {
float x, y, z;
Vector3 operator+ (const Vector3 v) {
return Vector3(x + v.x, y + v.y, z + v.z);
};
Vector3(float x, float y, float z) : x(x), y(y), z(z) {};
};
// and i use it inside some const function
struct SomeST {
Vector3 a,b;
Vector3 Function() const
{
return a + b; // error
}
};
and if i delete the const from function, it works!
so it would be amazing if someone can explain what's going on under the hood.
thanks.
Function
Vector3 Function() const
is const. Which means, that this is const inside the function. Which in turn means both a and b are const. a + b syntax is fancy way for writing a.operator + (b) (call operator + method on object a with argument b). Now a is const, so a.operator + method must also be const. Since you've not supplied such operator (the operator you've written is not const) your compiler highlights this as error and if you try to compile it, you will get const based error.
You need to suply operator + (...) const, which in this exact case means you need to add const keyword to definition:
Vector3 operator+ (const Vector3 v) const { ... }
This question already has answers here:
Can't Overload operator<< as member function
(3 answers)
Closed 4 years ago.
I have a struct that represents a 2d column vector. I've overloaded some operators such as * to mean scalar multiplication in the context of an int and + to mean vector addition in the context of another vector.
I also want to overload the << operator so that I can simply pass the object to cout and have the two elements printed. Currently I am overloading it like below;
struct vector2d
{
private:
float x;
float y;
public:
vector2d(float x, float y) : x(x), y(x) {}
vector2d() : x(0), y(0) {}
vector2d operator+(const vector2d& other)
{
this->x = this->x + other.x;
this->y = this->y + other.y;
return *this;
}
vector2d operator*(const int& c)
{
this->x = this->x*c;
this->y = this->y*c;
return *this;
}
friend std::ostream& operator<<(std::ostream& out, const vector2d& other)
{
out << other.x << " : " << other.y;
return out;
}
};
This works fine, but if I remove the friend keyword I get "too many parameters for this operator function". What does this mean and why does the friend keyword fix it?
With the friend, the operator is not a member of the class, so it requires 2 input parameters.
Without the friend, the operator becomes a member of the class, and thus requires only 1 parameter, so you would need to remove the vector2d parameter and use the hidden this parameter instead.
I'd like to overload the '+' operator for A struct but I'm getting compiler warning
Here's my attempt :
struct wektor{
int x;
int y=0;
int norm(){
return x*x+y*y;
}
};
wektor& operator +(wektor &a,wektor &b){
wektor c;
c.x=a.x+b.x; // 12 line - warning here
c.y=a.y+b.y;
return c;
};
Compiler warning:
[Warning] non-static data member initializers only available with -std=c++11 or -std=gnu++11 [enabled by default] in 12 line
The warning is telling you about the line:
int y=0;
You can't have an initialiser on a non-static non-const member prior to C++11. If you want to initialise y to 0 then you have to provide a constructor for wektor with a member initialization list.
Nonetheless, your operator+ parameters should be of type const wektor&. It should also return by value, because at the moment you're returning a reference to a local object that will be destroyed at the end of the function, and that is bad. It should look like this:
wektor operator +(const wektor &a, const wektor &b){
wektor c;
c.x=a.x+b.x; // 12 line - warning here
c.y=a.y+b.y;
return c;
};
First of all, binary operator+ should return a new value, not a reference. And if implemented in terms of references as input, these should be const:
wektor operator +(const wektor &a, const wektor &b);
Second, the warning is about this initialization:
struct wektor{
int x;
int y=0; // HERE! C++11 only
int norm(){
return x*x+y*y;
}
};
You can only do this in C++11. You could use a constructor in C++03.
struct wektor{
wector() : y() {} // zero-initializes y
int x;
int y;
int norm(){ return x*x+y*y;}
};
Going back to the operator+, I would implement an member operator+=, and then use it in a non-member operator+:
wektor operator +(wektor a, const wektor &b)
{
return a+= b;
}
Alternatively, give wector a two parameter constructor for x and y:
wector(int x, int y) : x(x), y(y) {}
ant then
wektor operator + (const wektor& a, const wektor &b)
{
return wector(a.x + b.x, a.y + b.y);
}
Not like that. The signature should be
wektor operator +(const wektor &a, const wektor &b)
I.e. don't return by reference from the + operator, and, even more importantly, don't return a temporary by reference.
That's a warning that you're using a feature from C++11, which isn't available in previous C++ standards.
When you know that what you've programed works the way you think, you can
get rid of this error by doing:
If you're using CodeBlocks:
Right-Click "Build Options..."
Select the "Other Options" tab
Add "-std=gnu++11"
If you're using the command line:
Add "-std=gnu++11" to the command arg's.
I have
Triangle::Triangle()
{
A = NULL;
B = NULL;
C = NULL;
}
Triangle::Triangle(Point& X,Point& Y, Point& Z)
{
A = new Point;
*A = X;
B = new Point;
*B = Y;
C = new Point;
*C = Z;
}
and
istream& operator>>(istream& in, Triangle& T)
{
Point X,Y,Z;
in>>X>>Y>>Z;
Triangle T(X,Y,Z);
return in;
}
Where Point is another class which defines a point with coordonates X and Y.
I don't know how to call the constructor with multiple arguments in the overloaded function. Can you help me?
This is how you do it:
Point px;
Point py;
Point pz;
Triangle trig(px, py, pz);
trig will be the object, which is an instance of class Triangle and the above would call the constructor with 3 Point arguments.
Another way is for pointers:
Triangle *pTrig = new Triangle(pX, pY, pZ);
In addition, I suggest, that this would be better:
Triangle::Triangle()
: A(NULL), B(NULL), C(NULL)
{
}
Triangle::Triangle(const Point& X,const Point& Y, const Point& Z)
: A(new Point(X)), B(new Point(Y)), C(new Point(Z))
{
}
Assuming that Point has a copy constructor.
You want to call it from inside the operator>> function to update argument T, but this won't work, because you cannot call the constructor on something that's already constructed. Instead, what you need is to implement an assignment operator. Please see http://en.wikipedia.org/wiki/Assignment_operator_%28C%2B%2B%29 for more information.
Then you can do T = Triangle(X,Y,Z);
To implement the assignment operator, you can do this:
Triangle& Triangle::operator= (const Triangle& other)
{
if (this != &other) // protect against invalid self-assignment
{
if (A != NULL) delete A;
if (B != NULL) delete B;
if (C != NULL) delete C;
A = new Point(other.A);
B = new Point(other.B);
C = new Point(other.C);
}
return *this;
}
Assuming Point has copy constructors. To implement copy constructors, please see http://en.wikipedia.org/wiki/Copy_constructor
A copy constructor looks like the following, but you need to do it for Point:
Triangle& Triangle::Triangle(const Triangle& other)
: A(new Point(other.A)), B(new Point(other.B)), C(new Point(other.C))
{
}
}
The first two constructors are overrides for default constructor. The third function is operator overloading which overloads >> operator. You just need to create an object of Triangle class as follow:
Triangle tr(x,y,z);
or
Triangle* tr = new Triangle(x,y,z);
Where x, y, and z are objects of Point class.
By the way, as you can see in your operator overloading (the third function), you are already creating an object of class Triangle (Triangle T(X,Y,Z);).
class Point {
public:
Point(int x, int y) : { x = new int(x); y = new int(y) }
...
...
Point& operator=(const Point& other) {
if(this!=&other){
delete x;
delete y;
x = new int(*other.x);
y = new int(*other.y);
}
return *this;
}
private:
const int* x;
const int* y;
}
Will this implementation of operator= work even if x and y of this were already initialized? does deleting a const pointer allow us to reassign it?
That's not a const pointer, but a pointer to const. So you can modify the pointer, you can't that which it points to.
A const pointer is
int* const x;
and your code wouldn't compile then.