Overloading = operator in c++ in case of strings - c++

I want to perform the following
int p = "xyz"
I should contain 3, i.e, the length of the string on the right side of =.
I tried making a class String with a char * data member but i was having trouble overloading the = operator since we have to pass atleast one object of the class we are overloading the operator for.
please help.
I tried to do the following:
friend void operator=(int, char*)
but it won't work since there is no argument of the class type.

It's impossible to do this, operator= is not overloadable for integer type.
See this answer.
If you use std::string, the solution is simple:
std::string p = "abc";
int l = p.size(); // Better than l = p, because self describing

Related

Overloading the Assignment operator for character Array in c++

It can be the worse questions I am going to ask but I want to overload the Assignment Operator for character Array so basically, I can use it as a string.
This is what I wanted to do.
char c1[]="This";
char c2[10];
c2 = c1;
This is what I have tried so far and yes it didn't work out.
#include<iostream>
using namespace std;
void operator = (char *c1, char *c)
{
for(int idx = 0; c[idx] != 0; idx++)
{
c1[idx] = c[idx];
}
c1[idx] = 0;
}
int main(void)
{
char c[] = "This";
char c1[10];
c1 = c;
return 0;
}
I want to overload the Assignment Operator for character Array
This is not possible. The C++ language does not allow defining operator overloads to anything other than classes.
Some alternatives:
Wrap the array as a member of a class and define assignment operator for that class. This is what std::array is, although it uses the implicit assignment operator which behaves differently from your operator (you cannot assign arrays of different size).
Just use a function instead of an operator. Your operator is pretty much identical to std::strcpy.
Note that the shown implementation is potentially unsafe (just like std::strcpy is) since it can easily accidentally overflow the target array.
use std::string
this will cause unpredictable results in a file handling.
std::string will not cause unpredicatble results in a file handling.

What does .*, ->* and .-> mean in C++?

I have been recently learning how to use the std::mem_fn library facility. In C++ Primer 5th edition they give an example of a usage of std::mem_fn, in the following code snippet svec is a vector of strings:
auto f = mem_fn(&string::empty); // f takes a string or a string*
f(*svec.begin()); // ok: passes a string object; f uses .* to call empty
f(&svec[0]); // ok: passes a pointer to string; f uses .-> to call empty
Note: In the above code snippet there is no use of ->*
Although I understand the usage .* and ->*. I don't have clarity on it.
So, My question is what does .*, ->*, .-> do?
You have an object o and a pointer to its member m. The operator .* allows you to access the pointed member of your object:
o.*m
You have a pointer to an object p and a pointer to its member m. The operator ->* allows you to access the pointed member of the pointed object:
p->*m
I am afraid that the operator .-> doesn't exist.
Operators .* and ->* call a member function (BTW there is no meaning for .-> in C++ - it's a syntax error).
These are binary operators. The left operand is an object (for .*) or a pointer to an object (for ->*), and the right operand is a pointer to a member (which can be a member field or a member function). The outcome of applying this operator is the ability to use a member field or a method.
Maybe these operators make sense from a historical point of view. Suppose you use a regular C pointer to a function:
typedef int (*CalcResult)(int x, int y, int z);
CalcResult my_calc_func = &CalcResult42;
...
int result = my_calc_func(11, 22, 33);
What if you decided to "rewrite" your program in an object-oriented way? Your calculation function would be a method in a class. To make a pointer to it, you need a new type, a pointer to member function:
typedef int (MyClass::*CalcResult)(int x, int y, int z);
CalcResult my_calc_func = &MyClass::CalcResult42;
...
MyClass my_object;
int result = (my_object.*my_calc_func)(11, 22, 33);
I always use this analogy when I try to remember the syntax of this .* operator - this helps because the regular pointer-to-function syntax is less convoluted and used more frequently.
Please note the parentheses:
int result = (my_object.*my_calc_func)(11, 22, 33);
They are almost always needed when using this .* operator, because its precedence is low. Even though my_object .* (my_calc_func(11, 22, 33)) is meaningless, the compiler would try to make sense of it if there were no parentheses.
The ->* operator works in essentially the same way. It would be used if the object on which to apply the method is given by a pointer:
typedef int (*MyClass::CalcResult)(int x, int y, int z);
CalcResult my_calc_func = &MyClass::CalcResult42;
...
MyClass my_object1, my_object2;
MyClass* my_object = flag ? &my_object1 : &my_object2;
int result = (my_object->*my_calc_func)(11, 22, 33);
The .* and ->* operators are called pointer to member access operators and like their name suggests they allow you to access an object's data or function member given an appropriate pointer to that class member.
struct foo
{
int a;
float b;
void bar() { std::cout << "bar\n"; }
};
int main()
{
int foo::* ptra = &foo::a;
float foo::* ptrb = &foo::b;
void (foo::* ptrbar)() = &foo::bar;
foo f;
foo * fptr = &f;
f.*ptra = 5;
f.*ptrb = 10.0f;
(f.*ptrbar)();
fptr->*ptra = 6;
fptr->*ptrb = 11.0f;
(fptr->*ptrbar)();
return 0;
}

Overloading the + operator

string operator + (const string &s, char *lit);
string operator + (const string &s, char *lit)
{
string temp;
temp.len = s.len+strlen(lit);
temp.str = new char[temp.len+1];
strcpy(temp.str, s.str);
strcat(tmep.str, lit);
return temp;
}
This is what my proffessor gave me as sample code as an example for overloading the string class. Thing is, when I compile it it says
std::string operator+(const string&, char*)’ must take either zero or one argument
I'm just wondering why it's not compiling? It'll take just one arg. but won't take two. Thanks.
I guess your professor meant namespace scope function (just usual function).
And you happened to declare non-static member function instead (I guess within some class named "blog").
operator+ accepts 1 or 2 arguments in namespace scope (binary operator+ accepts 2 arguments and unary operator+ accepts 1 argument) but as a non-static member function (in class scope) it accepts 0 or 1 argument (because it already has first implicit argument defined by this pointer).

Calling the parenthesis overload given a pointer

I can overload the parenthesis operator using the following signature:
char& operator()(const int r, const int c);
The intended usage of this would be:
// myObj is an object of type MyClass
myObj(2,3) = 'X'
char Y = myObj(2,3);
Which works as I expect. However, using the parenthesis operator when dealing with a pointer becomes convoluted. I would like to do:
// pMyObj is a pointer to an object of type MyClass
pMyObj->(2,3) = 'X';
char Y = pMyObj->(2,3);
However, such syntax yields the error Error: expected a member name (in VisualStudio at least).
The following does work but seems convoluted to me with a dereference and more parentheses than arguments.
char X = (*pMyObj)(2,3);
Is there a way to use the -> operator to call the () overload?
Yes there is, but you won't like it:
pMyObj->operator()(2,3);
You could also create a reference to the pointed to object and do
MyObj& rMyObj = *pMyObj;
char Y = rMyObj(2, 3);
which might be a good alternative if your code will be read by people who could be confused by
pMyObj->operator()(2,3);
if you do as below
#define SUB operator()
Then you can write things like this ...
pMyObj->SUB(2,3)
not as elegant as Fortran ;-) but perhaps not too ugly for actual use

question on operator overloading

I am trying to understand a program, which includes the following definition for a function f
void f(String S, const String& r)
{
}
Here String in the argument stands for a class. I am confused on the difference between the definitions of these two arguments: "String S" and "const String& r". S should represent an object of class String, then how about r?
In more detail, the f is defined as
void f(String S, const String& r)
{
int c1 = S[1]; // c1=s.operator[](1).operator char( )
s[1] ='c'; // s.operator[](1).operator=('c')
int c2 = r[1]; // c2 = r.operator[](1)
r[1] = 'd'; // error: assignment to char, r.operator[](1) = 'd'
}
This code snippet is to show how the operator overload, but these comments does not help me much. For instance, why r[1]='d' is nor correct? Thanks for helping understanding it.
const String& r is a constant reference to String r. Within the function, you access r just like a String. The difference is that it is actually a reference to the object passed to the function, while S will be a copy of the object passed to the function. You can almost think of it as if you are accessing r through a de-referenced pointer (though there is more to it than that).
Another way to look at it: The caller will see changes to r (if it wasn't const), while he will not see changes to S.
The const simply means the function f cannot modify r.
See also: https://isocpp.org/wiki/faq/references#overview-refs
This seems to be just an example, to show the difference between ways of passing parameters.
One real case where you might pass one parameter by value, is when you need a copy of the value anyway. Perhaps when concatenating the two strings.