Let us consider the following toy problem: implement a user-defined integer type MyInt which is assignment compatible with built-in signed and unsigned integers and supports addition. We assume here that all integers are 32-bit. Assigning unsigned integers above 0x7fffffff to MyInt and assigning negative MyInt values to unsigned integers should raise exceptions.

To begin with we have a record (Delphi)

```type
MyInt = record
private
FValue: Integer;
end;
```

or structure (C++)

```struct MyInt{
private:
int FValue;
};
```

By convention we use explicit conversion if a conversion can raise exception and implicit conversion otherwise. The Delphi solution is straightforward:

```unit MyInts;

interface

uses SysUtils;

type
MyInt = record
private
FValue: Integer;
public
class operator Implicit(AValue: MyInt): Integer;
class operator Explicit(AValue: MyInt): Cardinal;
class operator Implicit(AValue: Integer): MyInt;
class operator Explicit(AValue: Cardinal): MyInt;
class operator Add(A, B: MyInt): MyInt;
end;

implementation

class operator MyInt.Explicit(AValue: MyInt): Cardinal;
begin
if AValue.FValue < 0 then
raise Exception.Create(IntToStr(AValue.FValue));
Result:= AValue.FValue;
end;

class operator MyInt.Explicit(AValue: Cardinal): MyInt;
begin
if AValue > \$7FFFFFFF then
raise Exception.Create(IntToStr(AValue));
Result.FValue:= AValue;
end;

class operator MyInt.Implicit(AValue: MyInt): Integer;
begin
Result:= AValue.FValue;
end;

class operator MyInt.Implicit(AValue: Integer): MyInt;
begin
Result.FValue:= AValue;
end;

class operator MyInt.Add(A, B: MyInt): MyInt;
begin
Result.FValue:= A.FValue + B.FValue;
end;

end.
```

With C++ we need more to take into account. First C++ supports copy initialization

```  MyInt M = 1;
```

which is implemented by a constructor while a plain assignment requires either a conversion operator

```  MyInt M;
M = 1;
```

or an assignment operator

```  MyInt M = 1;
MyInt M1;
M1 = M;
```

If we do not declare an assignment operator C++ implicitly provides the one which implements assignment by shallow coping; it is enough for our problem.

Second we have 2 possible ways to implement the addition operator – as a member function or as a plain function. The member function treats the operands of a binary operation asymmetrically – the first operand is passed as this pointer (different from Delphi which implements the operator member function as static) – and rarely used. More common is to implement a binary operation by a plain function which should be declared as friend in MyInt structure to enable access to the private field FValue.

Third the conversion operators in C++ are “one-way”. We can define the conversion operator FROM MyInt; conversion TO MyInt is implemented by a constructor.

There are more language details a C++ programmer should have in mind while implementing operator overloading; you will discover them if you start experimenting with the code. I leave them out of the article.

Putting it all together we are coming to the following code:

(MyInts.hpp)

```#ifndef MYINTS_HPP_INCLUDED
#define MYINTS_HPP_INCLUDED

struct MyInt{
private:
int FValue;
public:
MyInt(int A = 0);
MyInt(unsigned int A);
MyInt(const MyInt& A);
//    MyInt operator=(MyInt A);

operator int();
operator unsigned int();
friend MyInt operator+(const MyInt& A, const MyInt& B);
};

#endif // MYINTS_HPP_INCLUDED
```

(MyInts.cpp)

```#include <iostream>
#include "MyInts.hpp"

using namespace std;

MyInt::MyInt(int A){
cout << "hello from MyInt(int) ctor" << endl;
FValue = A;
}

MyInt::MyInt(unsigned int A){
cout << "hello from MyInt(unsigned int A) ctor" << endl;
if (A > 0x7fffffff){
cout << "throwing " << A << endl;
throw(A);
}
FValue = A;
}

MyInt::MyInt(const MyInt& A){
cout << "hello from MyInt(const MyInt&) ctor" << endl;
FValue = A.FValue;
}

/*
MyInt MyInt::operator=(MyInt A){
cout << "hello from assignment operator" << endl;
FValue = A.FValue;
return *this;
}
*/

MyInt::operator int(){
cout << "hello from int conversion operator" << endl;
return FValue;
}

MyInt::operator unsigned int(){
cout << "hello from unsigned int conversion operator" << endl;
if (FValue < 0){
cout << "throwing " << FValue << endl;
throw(FValue);
}
return FValue;
}

MyInt operator+(const MyInt& A, const MyInt& B){
cout << "hello from addition operator" << endl;
MyInt Result = A.FValue + B.FValue;
return Result;
}
```