Overload + operator to concatenate strings using strcat() <cstring>

- Experts,

I am trying to overload the "+" operator to concatenate string using the function strcat(string dest, string src).
Looking at the signature of strcat, uses char *[] type for input arguments and return arguments. Therefore I am fighting with this types which seems to be a thing in cpp.
Here my code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <cstring>

using namespace std;

int main() {
	char a[10]="hola", b[10]="adios", c[10]="";

	c=a+b;
	return 0;
}

char[] operator+(char[] string1,const char[] string2) {
	strcat(string1, string2);
	return string1;
}


Can anyone tell me what I am doing wrong?

Thanks
Last edited on
- Experts,

I’m not, but I can quote other people answers:
https://stackoverflow.com/questions/23505423/why-c-operator-overloading-requires-having-at-least-one-parameter-of-class-ty
An operator function shall either be a non-static member function or be a non-member function and have at least one parameter whose type is a class, a reference to a class, an enumeration, or a reference to an enumeration.


(Plus: you should 'announce' your function to main() by a prototype).
I understand that my function operator is a non-static member function already.
Regarding one parameter whose type is a class, a reference to a class, an enumeration, or a reference to an enumeration. Would it work if I use a type struct? I saw some exercises that work overloading operator without defining a new class for the type. Does anyone know why?

1
2
3
4
struct cadena{
       char a[];
       int size;
}


Thanks

Would it work if I use a type struct?

Have you tried using a struct?

Since the only difference between a struct and a class is the default access specifiers you can treat a struct the same as a class.

wait...can the main actually reads the operator overloading function ?
if it is defined under main, there needs to be a prototype for the function above main
I finally have my program working:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <iostream>
#include <cstring>

using namespace std;


//Prototypes
struct cadena;
int comprobarLongitudCadena(const char *);
cadena operator+(cadena & , const cadena);

//Definitios
struct cadena {
	char* s;
	int size;
};

int main() {
	char a[10]="hola", b[10]="adios";
	cadena c,d,e;

	//Build the c struct
	c.size = comprobarLongitudCadena(a);
	cout << "La longitud de la cadena hola es: " << c.size <<endl;
	c.s = a;

	//Build the d struct
	d.size = comprobarLongitudCadena(b);
	d.s = b;

    //Concatenar cadenas utilizando el operador "+"
	e=c+d;

	cout << "Nueva cadena concatenada: ";
	for(int i=0; e.s[i]; i++){
		cout<<e.s[i];
	}

	cout <<endl;

	cout <<"Comprobamos que la cadena inicial tambiEn estA concatenada: ";
    for(int i=0; c.s[i]; i++){
    	cout <<c.s[i];
    }

	return 0;
}

int comprobarLongitudCadena(const char* cad){
	int i =0;
	while(cad[i]){
		i++;
	}
	return i+1;
}

cadena operator+(cadena & a,const cadena b) {
	strcat(a.s,b.s);
	a.size = comprobarLongitudCadena(a.s);
	return a;
}


If one type is a struct works.
To complete the explanation @jlb gave:
struct: default access specifiers public
class: default access specifiers private

Correct me if I am wrog but if a struct is defined in the class where main is, this struct is accessible by default from all the other classes.

@Flaze07: The prototype was also missing I added it.

Thanks.
It seems you want something which behaves differently than what std::string does. If you want your operator+ to modify the passed 'cadena’ and the ‘size’ of your ‘cadena’ to include the null terminating character, you’re doing great.
You can also simplify your code a bit, if you want:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <iostream>
#include <cstring>

struct cadena {
    char* s;
    size_t size; // Includes '\0' (vs std::strlen())
};

//Prototypes
cadena& operator+(cadena & , const cadena&);

int main() {
    char a[10] = "hola", 
         b[10] = "adios";
    cadena c, d, e;

    //Build the c struct
    c.size = std::strlen(a) + 1;
    std::cout << "La longitud de la cadena hola es: " << c.size << '\n';
    c.s = a;

    //Build the d struct
    d.size = strlen(b) + 1;
    d.s = b;

    //Concatenar cadenas utilizando el operador "+"
    e = c + d;

    std::cout << "Nueva cadena concatenada: " << e.s << '\n';

    std::cout << "Comprobamos que la cadena inicial tambien esta concatenada: "
               << c.s << '\n';
    return 0;
}

cadena& operator+(cadena & a, const cadena& b) {
    strcat(a.s, b.s);
    a.size = strlen(a.s) + 1;
    return a;
}


Correct me if I am wrog but if a struct is defined in the class where main is, this struct is accessible by default from all the other classes.

A struct is visible by the code that follows it’s declaration inside the same block.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>

void bFunc();

int main()
{
    struct A {
        char a {'a'};
    };
    A my_a;
    std::cout << "my_a.a is " << my_a.a << '\n';
    bFunc();
    return 0;
}

void bFunc()
{
    // Error: A is not visible here.
    // -->  error: 'A' was not declared in this scope
    /* A my_b;
    std::cout << "my_b.a is " << my_b.a << '\n'; */
}

@Enoizat: Thank you for the proposed code simplification and the scope of A explanation.

I am having again problems to overload operators. This time with the operator "=" to assign string arrays. This is my code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <iostream>
using namespace std;

class dumb_array
{
		int mSize;
		int* mArray;
	public:
		//default constructor
		dumb_array(int size = 0)
			: mSize(size)
			, mArray(0)
		{
			if(mSize!=0){
			mArray=new int [mSize];
			}
		}
		//copy constructor (def: non-template constructor whos first argument is T&, const T&, volatile T&, const volatile T&)
		dumb_array(const dumb_array& other);

		//destructor
		~dumb_array(){
			delete [] mArray;
		}

};

//Prototypes
dumb_array& operator=(dumb_array);

int main() {

	string a="hola", b;



	return 0;
}

dumb_array& operator=(dumb_array other){
	//Implementation

}


The error is "‘dumb_array& operator=(dumb_array)’ must be a nonstatic member function".
My questions are:
1) Why cannot be static?
2) Why has to be a member function?

According with what @Enoizat said:

An operator function shall either be a non-static member function or be a non-member function and have at least one parameter whose type is a class, a reference to a class, an enumeration, or a reference to an enumeration


In my case it is a non-member function and have at least one parameter whose is a class. Then why is the compiler complaining?
Then why is the compiler complaining?

Four operators cannot be non-members: operator=, (but operator+= can be non-member), operator(), operator[], and operator->
This is mentioned in the operator overloading overview on cppreference: http://en.cppreference.com/w/cpp/language/operators
Thanks @Cubbi
Topic archived. No new replies allowed.