#include <iostream>
using namespace std;
class A
{
public:
A(int a)
{
length = a;
}
~A(){}
friend A operator +(A& var1, A& var2);
A& operator=(A &other);
int length;
};
A operator +(A& var1, A& var2)
{
return A(var1.length + var2.length);
}
A& A::operator=(A &other)
{
length = other.length;
return *this;
}
int main()
{
A a(1);
A b(2);
A c(3);
c = a; // work
c = a + b; // does not work
cout << c.length ;
return 0;
}
In main(), c = a is successfully compiled but "c = a + b" is not.
However, in A& A::operator=(A &other), if I change (A &other) into (A other) then it works.
Can anyone help me with this case?
The simplest fix is to make your assignment overload take it's parameter by const reference.
Then the temporary returned by a + b can be used with it.
A& A::operator=(A const & other)
{
length = other.length;
return *this;
}
You'll probably want to do the same thing with your operator+ so that c = a + a + a; will work as well.
The problem is that operator + returns a temporary object
friend A operator +(A& var1, A& var2);
But a temporary object may not be bound to a non-const reference that is the type of the parameter of the assignment operator.
A& operator=(A &other);
So the compiler issues an error for statement
c = a + b;
You have three possibility.
The first one os to declare the parameter of the copy assignment operator as constant reference
A& operator=(const A &other);
It is the simplest approach.
The second one is to declare a move assignment operator instead of the copy assignment operator. In this case you explicitly need to define also a copy or move constructor. In this case instead of
c = a;
you have to write
c = std::move( a ); // work
For example
#include <iostream>
using namespace std;
class A
{
public:
A(int a)
{
length = a;
}
~A(){}
friend A operator +(A& var1, A& var2);
A& operator=(A &&other);
A( A && ) = default;
int length;
};
A operator +(A& var1, A& var2)
{
return A(var1.length + var2.length);
}
A& A::operator=(A &&other)
{
length = other.length;
return *this;
}
int main()
{
A a(1);
A b(2);
A c(3);
c = std::move( a ); // work
c = a + b; // does not work
cout << c.length ;
return 0;
}
And at last you could have the both operators simultaneously. For example
#include <iostream>
using namespace std;
class A
{
public:
A(int a)
{
length = a;
}
~A(){}
friend A operator +(A& var1, A& var2);
A& operator=(const A &other);
A& operator=(A &&other);
A( const A & ) = default;
int length;
};
A operator +(A& var1, A& var2)
{
return A(var1.length + var2.length);
}
A& A::operator=(const A &other)
{
length = other.length;
return *this;
}
A& A::operator=(A &&other)
{
length = other.length;
return *this;
}
int main()
{
A a(1);
A b(2);
A c(3);
c = a; // work
c = a + b; // does not work
cout << c.length ;
return 0;
}
In this case in statement
c = a; // work
there will be called the copy assignment operator and in statement
c = a + b; // does not work
there will be called the move assignment operator.
Of course you also may have the copy constructor and move constructor simultaneously the same way as the copy assignment operator and the move assignment operator. For your class you could all them define as defaulted.
For example
#include <iostream>
using namespace std;
class A
{
public:
A(int a)
{
length = a;
}
~A(){}
friend A operator +(A& var1, A& var2);
A& operator=(const A &other) = default;
A& operator=(A &&other) = default;
A( const A & ) = default;
A( A && ) = default;
int length;
};
A operator +(A& var1, A& var2)
{
return A(var1.length + var2.length);
}
int main()
{
A a(1);
A b(2);
A c(3);
c = a; // work
c = a + b; // does not work
cout << c.length ;
return 0;
}
Related
In the code below std::deque compiles, but std::queue does not:
class A
{
public:
explicit A(int a) : m_a(a)
{
++count;
}
~A()
{
--count;
}
A(A const &) = delete;
A(A && other) : A(other.m_a)
{
other.m_moved = true;
}
A & operator = (const A &) = delete;
A & operator = (A && other)
{
m_a = other.m_a;
other.m_moved = true;
return *this;
}
bool operator == (const A & other) const
{
return m_a == other.m_a;
}
bool operator != (const A & other) const
{
return !operator==(other);
}
bool operator < (const A & other) const
{
return m_a < other.m_a;
}
static int count;
private:
bool m_moved = false;
int m_a;
};
int A::count = 0;
int main()
{
std::deque<A> d;
std::queue q(d);
q.push(A(1));
return 0;
}
but if I make class A copyable by changing A(A const &) = delete; with A(A const &) = default; it starts to compile.
What is the logic behind this? As far as I can see, std::deque is an adapter that does not add some extra functionality.
Elements are copied when you construct queue from deque, but you've deleted copy constructor for deque's value type (A). So you need to move d when constructing queue.
...
int main()
{
std::deque<A> d;
std::queue q(std::move(d)); // added std::move
q.push(A(1));
return 0;
}
I wanted to clear / reinstansiate a instance of a class using the assignment operator, but some members in that class have their assignment operator deleted. So when i try to assign it to a new instance it keeps its old values.
Heres a example:
#include <cstdio>
class C
{
C operator= (const C&) = delete;
};
class B
{
public:
int x = 0;
C c;
B& operator=(const B& other)
{
return B();
}
};
int main()
{
B b;
b.x = 5;
b = B();
printf("%i\n", b.x); // prints 5, should print 0
return 0;
}
Is there some simple workaround for this without writing a method that clears all of its members? Why does this happen?
Why does this happen?
Your current implementation of operator=() is fubar.
B& operator=(B const &other)
{
x = other.x;
return *this;
}
you should also test for self-assignment, before you do anything, though, since copying members can be quite expensive:
B& operator=(B const &other)
{
if(this != &other)
x = other.x;
return *this;
}
I just build a mini program to understand how this will work because i need this for something a bit more difficult but i can't make this work.
I think i need to define operator overload but i dont know how because they are two objects of set<set<a>>
If you compile you will see a big error where it notice that he can't compare myset == myset2 and i think it will say same for operator != and =
#include <set>
using namespace std;
class a{
private:
int a_;
public:
int get_a() const{ return a_; }
void set_a(int aux){ a_=aux;}
bool operator < (const a& t) const{
return this->get_a() < t.get_a();
}
};
class b{
private:
set<set<a> > b_;
public:
void set_(set<a> aux){ b_.insert(aux); }
//Overload operators?
};
int main(){
b myset;
b myset2;
set<a> subset1;
set<a> subset2;
a myint;
myint.set_a(1);
subset1.insert(myint);
myint.set_a(2);
subset1.insert(myint);
myint.set_a(3);
subset1.insert(myint);
myint.set_a(5);
subset2.insert(myint);
myint.set_a(6);
subset2.insert(myint);
myint.set_a(7);
subset2.insert(myint);
myset.set_(subset1);
myset.set_(subset2);
myset2.set_(subset1);
myset2.set_(subset2);
if(myset == myset2){
cout << "They are equal" << endl;
}
if(myset != myset2){
cout << "They are different" << endl;
}
b myset3;
myset3 = myset2; //Copy one into other
}
In order for your code to work you need to specify following operators (note: they are not created by default)
class a{
private:
int a_;
public:
int get_a() const{ return a_; }
void set_a(int aux){ a_=aux;}
/* needed for set insertion */
bool operator < (const a& other) const {
return this->get_a() < other.get_a();
}
/* needed for set comparison */
bool operator == (const a& other) const {
return this->get_a() == other.get_a();
}
};
class b{
private:
set<set<a> > b_;
public:
void set_(set<a> aux){ b_.insert(aux); }
/* needed, because myset == myset2 is called later in the code */
bool operator == (const b& other) const {
return this->b_ == other.b_;
}
/* needed, because myset != myset2 is called later in the code */
bool operator != (const b& other) const {
return !(*this == other);
}
};
You should also take a look at http://en.cppreference.com/w/cpp/container/set and see what other operators std::set uses internally on its elements.
No operator (except for the default operator=(const T&) and operator=(T&&)) is generated by the compiler by default. You should define them explicitly:
class b{
private:
set<set<a> > b_;
public:
void set_(set<a> aux){ b_.insert(aux); }
//Overload operators?
bool operator==(const b& other) const {
return b_ == other.b_;
}
bool operator!=(const b& other) const {
return b_ != other.b_;
}
};
However, this only does not solve the case. Although comparison operators are already defined for std::set<T>, they only work if there are operators for T. So, in this case, you have to define operator== and operator!= for your a class in the same manner as I showed you with b class.
What operators I need to overload to make this word?
Variables A1 and A2 both of type class A, variable floatValue is of type float.
A1 += A2 * floatValue;
I have overloaded this operators
A operator+() const;
A operator+=(const A value);
A operator*(const A value);
friend A operator*(const A val2, float val);
But, I receive error "Class A has no suitable copy constructor"
I have this constructors in my class
A();
A(float val1, float val2);
A(float value);
Thanks for answering.
Minimal example:
#include <iostream>
using namespace std;
struct foo {
float val;
foo(float val): val(val){}
foo &operator+=(foo const &other) {
this->val += other.val;
return *this;
}
friend foo operator*(foo const &lhs, foo const &rhs) {
return lhs.val*rhs.val;
}
};
int main() {
foo a = 5, b = 6;
a += b * 3;
cout << a.val << endl;
return 0;
}
see: http://ideone.com/6pD2pr
With an explicit constructor you might want to use this example instead:
#include <iostream>
using namespace std;
struct foo {
float val;
explicit foo(float val): val(val){}
foo &operator+=(foo const &other) {
this->val += other.val;
return *this;
}
friend foo operator*(foo const &lhs, float val) {
return foo(lhs.val*val);
}
};
int main() {
foo a(5), b(6);
a += b * 3;
cout << a.val << endl;
return 0;
}
see: http://ideone.com/o8Vu1d
Whenever you overload an assignment operator like
A operator+=(const A value);
you also need to define a copy constructor like
A( const A& );
The copy constructor will be used by the assignment operator.
This is part of what's known as the Rule of Three.
When you have function like this:
fun(A a);
Arguments here are passed by value, so you need to have copy constructor for A (in order to create new instance from another instance), OR you can change it to reference, so no copy constructor will be needed.
Like this:
A operator+=(const A &value);
I encountered this code but I could not understand the functionality of this code.
It would be a great help if someone could explain it .
struct A{
int i,j;
A(int ii,int jj) : i(ii),j(ii){}
A(const A&a){
}
A& operator =(const A& a){
i=a.i;j=a.j;
}
};
int main()
{
int i;
A a(1,2);
A b(2,3);
A z = (a=b);
cout<<z.i<<" "<<z.j<<endl;
system("pause");
return 0;
}
Explanation:
struct A{
int i,j;//members i and j
A(int ii,int jj) : i(ii),j(ii){} //A constructor. Short form of A(int ii,int jj){i = ii;j = jj;} Original code is wrong too. Should be j(jj) instead of j(ii)
A(const A&a){}//Another constructor. It is missing the assignment
A& operator =(const A& a){
i=a.i;j=a.j;
}//Equal operator overload definition for A = another A. It copies the data from another A and assign to this new one
};
Complete working code:
#include <iostream>
using namespace std;
struct A{
int i,j;
A(int ii,int jj) : i(ii),j(jj){}
A(const A&a){i=a.i;j=a.j;}
A& operator =(const A& a){i=a.i;j=a.j;}
};
int main()
{
int i;
A a(1,2);
A b(2,3);
A z = (a=b);
cout<<z.i<<" "<<z.j<<endl;
return 0;
}
Your problem is this line:
A z = (a=b);
It ends up invoking both your operator= method and your Copy Constructor. When a = b is executed, it uses the operator= method because a already exists and then a reference to a is returned. You're essentially calling a.operator=(b).
When A z = ... is executed, it actually uses the Copy Constructor A(const A&a), not the operator= method because z does not exist yet. Since z is being created by that copy constructor and i and j are never initialized, when you try to print them out, you get whatever junk was located in the memory reserved for i and j.
Another way to view this line:
A z = (a=b);
Is actually like this:
A z(a.operator=(b));
Here's a full example:
int main()
{
A a(1,2);
A b(2,3);
a = b; //calls A& operator=(const A& a)
A z = a; //calls A(const A& a)
}
In conclusion, the fix is to do this:
A(const A& a)
{
i = a.i;
j = a.j;
}
Three mistakes:
1.A(int ii,int jj) : i(ii),j(ii /* jj here? */){}
2.The copy constructor should initialize the members: A(const A&a): i(a.i), j(a.j) {}
3.You should Add return *this in operator=:
A& operator =(const A& a){
i=a.i;j=a.j;
return *this;
}
The OP has asked the operator overloadin part. if we take a as const how can we edit it.
The operator overloading part is:
A& operator =(const A& a){
i=a.i;j=a.j;
}
When you write a=b, you only expect a to change and not b. This is enforced by the const specifier in the function argument definition. This const specifier has nothing to do with whatever appears on the left hand side of the equal sign. It only says that the right hand side of the equal sign will not be modified.