I have doubt whether we can do the following or not.
Suppose I have created two instance of class A i.e. obj1 and obj2 and class A has member function show().
Can I use the following?
(obj1+obj2).show()
If yes, how? If no, why it is not possible?
Yes it is possible, just implement operator+ for A and have it return a class of type A:
#include <iostream>
class A
{
public:
explicit A(int v) : value(v) {}
void show() const { std::cout << value << '\n'; }
int value;
};
A operator+(const A& lhs, const A& rhs)
{
A result( lhs.value + rhs.value );
return result;
}
int main()
{
A a(1);
A b(1);
(a+b).show(); // prints 2!
return 0;
}
You can do it if you overload the + operator in such a way that it takes two arguments of type A and yields an object that has a method named show.
Yes you can use it if you have overloaded the + operator of class A to return an obect of class A.
If obj1+obj2 does return an object that have a show() function member, then yes it's possible.
If not, it is not.
So, it depends on the operator+ function that is used here, that depends on both types of obj1 and obj2.
obj1+obj2 is an expression that have a type, the type of the object returned by the operation, like any expression. Now, once the expression is executed, you have this object. But as here you don't associate it to a name (using assignation for example), it is a "temporary", meaning it will be destroyed at the end of the full expression.
So, if the resulting temporary object's type does provide a show() function then you can call it like you did.
If it don't provide a show() function, then you're trying to call a function that don't exists.
So in any case, the compiler will stop you, it will not be a runtime error.
I would be you, I would setup a minimal test project just to play with those principles.
Write an operator overload for + operator and define the operation you want on that.
In the operator overload for + operator just update the logic you want like adding the individual member variables or concatenating the names etc meaningfully based on your use case
Then you can call That new object.Show() function just like an object calling member function.
Depends on what the result type of obj1+obj2 is and whether .show() is a constant method.
No! The result of (obj1+obj2) isn't object. You may overload "="
and use:
obj3 = obj1 + obj2;
obj3.show();
Related
I create a two pointer object of a class 'myclass'
myclass *obj1,*obj2;
can I compare these two objects using comparison operator and pointer expression i.e *obj1==*obj2
If yes, how does it happen?
If not, why isn't his allowed?
If yes, how does it happen?
If not, why isn't his allowed?
In short the answer will be yes if you have defined a suitable operator == function for comparing myclass instances and no if you have not defined a suitable operator == function.
There are two ways to declare an operator == function - as a member function of the MyClass class or as a non-member function (sometimes called a global function or free function).
Declaring a MyClass member function might look something like this...
class MyClass
{
public:
bool operator == (const MyClass &rhs) const
{
bool result{ false };
// calculate result;
return result;
}
// ... etc ...
};
Given the statement if (*obj1 == *obj2) the member function above would be called on the *obj1 instance (i.e., this would refer to *obj1) while the *obj2 instance would be passed as the argument to the parameter rhs.
Alternatively, the equality comparison operator for MyClass could be declared as a non-member (aka global) function...
bool operator == (const MyClass &lhs, const MyClass &rhs)
{
bool result{ false };
// calculate result;
return result;
}
In this case, given the statement if (*obj1 == *obj2) the function above would be called with the *obj1 instance passed as the argument to the lhs parameter and the *obj2 instance passed as the argument to the rhs parameter.
You cannot declare both a member function and a non-member function operator == using the same signature. The compiler wouldn't be able to decide which one to call!
Whichever technique you use to declare an operator == function, the "calculate result" code can be absolutely anything that makes sense for your particular class, so long as it returns true or false.
Typically you would compare the various members of the two objects and return true if those members held the same values. But you might not compare all members. Consider, for example, the following Book class...
class Book
{
public:
std::string Title;
std::string Author;
std::string Isbn;
// ... etc ...
};
You might decide that operator == should return true only if the two instances have equal ISBN values because different editions of a book like The Hitchhiker's Guide To The Galaxy should be considered different. Alternatively you might decide that two Book instances are equal if they have the same Title and Author because paperback and hardback editions of the Guide might have different ISBNs but they're still (in some sense) the same book.
Finally(!) it should be noted that while the sample code above uses const MyClass & as the type for the rhs parameter C++ does not require that the rhs parameter be the same type as the lhs parameter.
Normally it would be of course, and defining an operator == function that compared two dissimilar types would be likely to confuse readers and could cause problems for programmers using your class. But, as is often the case, if you think you know what you are doing, C++ won't get in your way.
If you'd like to read more about comparison operators you might find http://en.cppreference.com/w/cpp/language/operator_comparison interesting.
Yes, this will work, but only if you've overloaded the == operator for your class. If you have, then == will invoke the appropriate operator== method, which implements the equality test for your class. In other words, it's up to you to define what equality means for your class.
== operator on pointers will compare their numeric address and hence determine if *obj1 and *obj2 points to the same object or not.
bool operator==(const myclass &obj2); // in this method, see if obj2 is equal to *this.
The code you are suggesting will work only if myclass defines operator==.
And as Jeremy Friesner pointed out, you need to beware of invalid pointers, in particular the value NULL (or nullptr).
So what you really want is:
if ((obj1 != nullptr) && (obj2 != nullptr( && (*obj1 == *obj2)) ...
I would also recommend changing those identifiers to ptr1 and ptr2, as "obj1" and "obj2" would imply to the average reader that they are objects rather than pointers to objects. Or myclsptr1 and myclsptr2, as an indication to the reader of what sort of thing they point to. Or, better yet, names that indicate what their purpose is in this part of the program.
can I compare these two objects using comparison operator and pointer expression i.e *obj1==*obj2
Synactically speaking, you can do that only if the operator is defined for the class. You can do that by overloading the operator== function, which can be a member function or a non-member function.
It will work at run time only if obj1 and obj2 point to valid objects.
If obj1 and obj2 point to valid objects, *obj1 == *obj2 will work just like if you had
MyClass o1;
MyClass o2;
and used o1 == o2
1.Pointer to a class is similar-to pointer to a Structure where if you want to compare you have to access and compare each and every member.
2.You can compare obj1==obj2(which compares address) but if you want to compare two objects *obj1==*obj2 you have to overload "==" operator in your "myclass" like this:::
bool operator==(const myclass& b) {//Compare methods or variables of both objects and return result bool(true/false)
This is a rather simple concept. I have an arithmetic operator and I wish for the operation to update not create an object. Essentially,
MyType A;
MyType B;
MyType C;
A = B - C;
A = C - B;
The statement A = B - C should not call the constructor for MyType again since A is already created, i.e. the constructor should only be called 3 times in this program. Is there some way to achieve this while maintaining a nice syntax? I suspect that I could let the operator function know not to create an object but rather to use some reference. Is there a more streamlined way to do this using some c++ syntax unknown to me?
class MyType
{
MyType* OperatorReturnObj;
MyType operator-(const MyType& Left, const MyType& Right)
{
// This removed and replaced with SetOperatorReturnObj function
// MyType OperatorReturnObj();
OperatorReturnObj= Left - Right;
return OperatorReturnObj;
}
void MyType SetOperatorReturnObj(MyType* Ref)
{
OperatorReturnObj = Ref;
}
};
Without ugly tricks like creating pool of objects and using them internally (where complications would be more expensive than any benefits for this case), there is no way to achieve this. Problem is that statement:
A = B - C;
is equal to:
A.operator=( operator-( B, C ) );
as you can see operator-( B, C ) has to be executed first and provide result somewhere. So you either have to change syntax like:
A += B; A -= C; // or even
(A += B) -= C; // or maybe
A += B -= C;
or use regular syntax and if you need efficiency implement move semantics.
After some thought you can create object of type MyTypeExression which does not do actual calculations but remember arguments and operations and only do them later when MyType::operator=(MyTypeExression) is executed. Though for that to work you probably need a wrapper with smart pointer for MyType so MyTypeExression does not have to copy it's arguments. So this solution can be considered as complicated trick I mentioned before.
I wish for the operation to update not create an object
For A = B - C;, A will be updated, by operator=.
More particular, operator- 's return value is passed by value, a temporary variable has to be created inside operator- and then copied/moved to A.
BTW1: OperatorReturnObj= Left - Right; will cause an infinite recursion.
BTW2: MyType A(); is a function declaration indeed. Most vexing parse
You cannot.
In A = B - C, first the B - C expression is evaluated. Then the result is copied to A.
The B - C expression knows nothing about A, so it is not possible to update A directly.
You can overload the assignment operator but this will not prevent the creation of a new object.
Some tips:
First of all, you didn't specified how to initialize the internal pointer attribute, so at this moment it points to an unspecified value in the memory stack.
Second, the operator- method(!) isn't defined like you did. look at "binary arithmetic operators"
binary operators have to return a reference to the object they are called from.
Third, the object itself is passed "automagically" to its methods, and its available as the this pointer.
So you don't have to pass it as the first parameter.
Finally, to return a reference you have to return the value, and not the pointer : --> *this.
So an expression like A=B+C is evaluated to:
A.operator=(B.operator+(C))
So B+C is different than C+B. (I don't enter in the details of inheritance here..)
Inspired from the same previous link above:
class X {
int internalprivatevalue;
//....
public:
X& operator+(const X& second) {
// actual addition of second to *this takes place here
// e.g. internalprivatevalue+=second. internalprivatevalue;
return *this; // return the result by reference!!
}
}
Hope to have clarified a little more your doubts.
this might be a noobie question but this confuses me, especially when it comes to this pointer.
How do I know which object "this" pointer is pointing to? I can provide an example where that confuses me... Say you had this code
#include<iostream>
using namespace std;
class someClass{
int var;
//2 constructors here, one with no arguments, one with giving a value to var(not important)
someClass operator+(someClass object){
someClass rObject;
rObject.var = this->var + object.var //and here is my problem
}
};
int main() {
someClass a(20);
someClass b(30);
someClass c;
c=a+b; //????????
//rest of the code not important
}
In this case the "current object" would be the object a, but how does that make sense if we just switch sides so it's c=b+a the current object would become b... I am confused... What determines the current object?
You have chosen the more involved example: operators. In general it is easier to reason about other member functions. Consider:
struct T {
int value;
void foo() { std::cout << this->value << '\n'; }
};
int main() {
T t;
t.foo();
}
How do you know which is the current object inside foo()? It is the object on the left of the dot operator in the expression, in this case t. (Well, in this case there is no other object at all in the program!)
Now going back to operators, for binary operators in particular, many of them can be implemented in two forms, as a free function taking two arguments or as a member function taking a single argument. There is a direct transformation that the compiler will do for you in both cases:
struct T {
int value;
T operator+(T const & rhs) { T tmp; tmp.value = this->value + rhs.value; return tmp; }
};
T operator-(T const & lhs, T const & rhs) {
T tmp; tmp.value = lhs.value - rhs.value; return tmp;
}
int main() {
T a, b; a.value = 1; b.value = 2;
a - b;
a + b;
}
Then the compiler encounters the expression a - b it searches for the two possible forms of the operator, it finds that it is a free function and it binds lhs to a and rhs to b, transforming the expression into operator-(a, b). In the case of a + b, the compiler again searches for the operator and finds it as a member function, at this point the transformation becomes a.operator+(b) and the this pointer inside the member function refers once again to the object to the left of the dot operator.
Non-static class methods have an implicit first argument this of the class type. So when you write:
operator+(someClass object)
You are actually getting this:
operator+(someClass* this, someClass object)
And now you can see: the left-hand side of a binary operator is the first argument, and the right-hand side is the second argument (by convention, and because it makes more sense than the other way around).
When you execute a+b, that invokes operator +(someClass) on object a. Therefore, this is a.
It helps to first consider an easier operator, namely operator +=. It may appear to be a more advanced operator, but that's because we learned arithmetic using +. If you look at your code, you see that you typically need three objects for + c=a+b whereas += just needs two: b += a.
Now in b += a the this pointer should point to the object you're changing, i.e. b. That's the first object. To keep things simple, for all binary operators this points to the first object.
I am a beginner in C++, and this must be a really basic question. I understand & stands for referencing operation. For example, a = &b assigns the address of b to a. However, what does & in a declaration such as the following mean?
className& operator=(const className&);
Do the following make sense and what is the difference between the last line and the following?
className* operator=(const className*);
From the answers below, it seems --- as I understand it --- that the following is valid too. Is it? If it is, how is it different from the version with "&"?
className operator=(const className);
After reading the following answers and some more outside, I realized part of my original confusion stems from mixing up reference as in general computer science and reference type as in C++. Thank you all who answered my question. All the answers clarify my understanding to different degrees, even though I can only pick one as the accepted answer.
The token & has three distinct meanings in C++, two of which are inherited from C, and one of which is not.
It's the bitwise AND operator (unless overloaded).
It's the address operator, which acts on an lvalue to yield a pointer to it. (Unless overloaded.) This is what is happening in a = &b.
It denotes a reference type. const className& as a parameter is a const reference to an object of type className, so when the function is called, the argument will be passed by reference, but it won't be allowed to be modified by the function. The function you gave also returns a reference.
Assignment Operator
Understanding is best gained by example:
class A {
int x;
public:
A(int value) : x(value) {}
A& operator=(const A& from) { // Edit: added missing '=' in 'operator='
x = from.x;
return *this;
}
};
A m1(7);
A m2(9);
m2 = m1; /// <--- calls the function above, replaces m2.x with 7
Here, we defined the assignment operator. This special method is designed to provide assignment capability to objects.
The reason that it returns a reference to *this is so you can chain assignments without excessive memory copies:
A m3(11);
m3 = m1 = m2; /// <--- now, m3.x and m1.x both set to m2.x
Expanded as follows:
m3 = ( something )
where
(something) is a reference to the object m1
by result of call to m1.operator=(m2) method
such that
the returned reference is then passed into m3.operator(...)
Chaining lets you do this:
(m1=m2).function(); // calls m1.function after calling assignment operator
Libraries such as boost leverage this pattern (for a different type of chaining example, see the program options library in boost) and it can be useful when developing a domain specific 'language'.
If instead full objects were returned from operator=, the chained assignment would at a minimum involve multiple extra copies of the objects, wasting CPU cycles and memory. In many cases things would not work properly because of the copy.
Essentially, using a reference avoids a copy.
Note
In reality, (simplified explanation) a reference is just a fancy syntax for a C pointer.
In the common case, you can then write code with A.x instead of A->x.
Caution
Returning a pure reference from a method is often dangerous; newcomers can be tempted to return a reference to an object constructed locally inside the method on the stack, which depending on the object can lead to obscure bugs.
Your pointer example
It depends on what you return from the body of the method, but regardless, the following would instead return a pointer to some instance of className:
className* operator=(const className*);
This will compile and it even seems to work (if you return this from the method), but this does violate the Rule of Least Surprise, as it is likely anyone else attempting to use your code would not expect the assignment operator to return a pointer.
If you think about base types:
int x=1; int y=2; int z; z=y=x;
will never ever do anything other than return integers - so having operator= return the assigned to object is consistent)
It also doesn't let you do this:
(m1 = m2).something
It also allows you to pass NULL which is something assignment operators don't typically want to care about.
Instead of writing
blah& operator(const blah& x) { a = x.a ; return *this; }
You would need to write:
blah* operator(const blah* x) {
if (x) { a = x->a ; return this; }
else { /*handle null pointer*/
}
It means the function takes a reference to a const className and returns a reference to a className
Say you have a class like below:
class className
{
public:
className& operator=(const className& rhs)
{
this->a_ = rhs.a_;
this->b_ = rhs.b_;
return *this;
}
private:
std::string a_;
std::string b_;
};
You can use the assignment operator of the class as below:
className a;
className b;
className c;
c = b = a;
The above line is executed as:
c.operator=(b.operator=(a));
Now take another class that has the operator= defined using the second form:
class className2
{
public:
className2* operator=(const className2* rhs)
{
this->a_ = rhs->a_;
this->b_ = rhs->b_;
return this;
}
private:
std::string a_;
std::string b_;
};
You can use the assignment operator of the class as below:
className2 obj1;
className2 obj2;
className2 obj3;
obj2 = &obj1;
obj3 = &obj2;
The above lines are executed as:
obj2.operator=(&obj1);
obj3.operator=(&obj2);
However, such coding is not intuitive. You don't assign a pointer to an object. It is more intuitive to say:
className obj1;
className* objPtr = NULL;
objPtr = &obj1;
a = &b
Here, & gives address of b.
className& operator=(const className&);
Here, operator = will take const reference of variable of type className.
You can say in C++, & is polymorphic.
Why does the below C++ program output "ACCA"? Why is operator int() called twice?
#include "stdafx.h"
#include <iostream>
using namespace std;
class Base {
public:
Base(int m_var=1):i(m_var){
cout<<"A";
}
Base(Base& Base){
cout<<"B";
i=Base.i;
}
operator int() {
cout<<"C";
return i;
}
private:
int i;
};
int main()
{
Base obj;
obj = obj+obj;
return 0;
}
First, this line:
Base obj;
Default-constructs object obj by picking the constructor that accepts an integer, with default value 1. This is responsible for the first A being printed to the standard output.
Then, this expression:
obj + obj
Requires picking a viable overload of operator +. In this case, since obj has a user-defined conversion to int, the built-in operator + is picked, and both arguments are converted to int. This is responsible for the two Cs being printed to the standard output.
Then, the assignment to obj in:
obj = obj + obj
Needs to invoke the implicitly generated operator = for Base. The implicitly generated operator = has signature:
Base& operator = (Base const&);
This means that the expression on the right side of the equal sign, which is of type int, must be converted into a temporary Base object from which obj is assigned (the reference parameter of the implicitly-generated operator = is bound to this temporary).
But the creation of this temporary from an int in turn requires invoking the converting construction of Base that accepts an int again, which is responsible for the second A being printed to the standard output.
operator int() is called twice because you haven't overloaded operator+. The compiler doesn't know how to add a Base to a Base, so they are converted to int (since you taught it how to do that), which it does know how to do. The following code prints ADA:
#include <iostream>
using namespace std;
class Base {
public:
Base(int m_var=1):i(m_var){
cout<<"A";
}
Base(Base& Base){
cout<<"B";
i=Base.i;
}
operator int() {
cout<<"C";
return i;
}
int operator+(Base& Base)
{
cout<<"D";
return i+Base.i;
}
private:
int i;
};
int main()
{
Base obj;
obj = obj+obj;
return 0;
}
When you construct the object, you get the first "A":
Base obj;
When you specify to add obj+obj, the compiler needs to figure out a way to use + on obj. Since you didn't override an operator+ for Base, the conversion to int() gets called for each side of the equation:
obj+obj
This prints "CC".
Then, you assign to obj, which is of type Base, so the constructor which can accept an int (i + i from the int() operator) is run, which prints "A":
obj = obj+obj; // Assignment prints "A"
obj = obj+obj;
^^^--------obj converted to int here
^^^----obj converted to int here
^^^^^------------Base(int) ctor and default operator= called here
Overloading cast operators is not generally a good idea unless you understand the costs and know for a fact that the benefits in your specific case outweigh them.
how does below C++ program computes to "ACCA" ?
The first letter shown is 'A'. This output is related to this line:
Base obj;
... in which you are creating a new instance of Base.
The next line is a bit complicated:
obj = obj+obj;
Normally, this is translated to obj.operator+( obj ), but you don't have operator + overloaded in class Base, so this translation is not valid. The remaining possibility is that operator + is actually the numeric add operator.
And yes, this is possible, since you have provided a cast to int. So it is possible to convert each term of the equation in an int... and therefore operator int is called twice. The actual number of times operator int is called depends on the optimizations activated. For example, the compiler could realise that both terms are the same, and then create a new temporary once the operator int has been called the first time. In that case, you would see CA instead of CC.
Finally, the assignment expression obj.operator=( temp ) is executed. And here the keyword is temp. In order for the default operator= to work, since it is not overloaded, you have to have a Base object at the right. It is actually possible to have it, since Base uses an int to build new instances. Okay, so the result of obj + obj was an int (say it is called 'x') number, and the compiler creates a temporary object of class Base which is constructed with number x, as the following line was executed:
Base temp( x );
That's the way the final letter seen is an 'A'. Again, many compilers can avoid the building of temporaries on some cases, so it is possible not to see an 'A' at the end.
Note that this line:
obj = obj + obj
Was thus decomposed in:
int x = ( (int) obj ) + ( (int) obj );
Base temp( x );
obj = temp;
The final instruction has the result of as if the memory in which obj sits will be occupied with the contents of temp (that's the role of the default copy constructor, which executes operator= for each member of the class, see again the 'rule of three').
Operator overloading involves a lot of issues that maybe are not foreseen if you don't have a more or less deep knowledge of the language, as you can see. Take also into account that languages like Java totally prevent its use, while C# permits it from a controlled perspective.
You refer to obj twice in the expression obj+obj and each such reference has to be converted to an integer.
It's not impossible (although it is a horrible idea) that such a conversion could be "stateful" - that is, it could by design return a different value each time it is called. After all, the value represented by obj may change (it could be a counter or something like that). So the compiler has to evaluate it afresh for each reference.
It's call once per operand, it doesn't matter if it is the same instance.
obj = obj+obj;
It "casts" the first operand to an int, and then the second one.
You need to overload the operator + if you want to avoid this implicit cast.
It calls operator int() twice because it needs to convert both obj to int before it can add them.
The first A comes from
Base obj;
The two Cs come from converting obj in obj+obj to int as you didn't overload the operator +.
The last A comes from obj = conversion of the resulting int to obj.