Overload Operators for referenced objects?

J

Jonas Huckestein

hello,

somehow i can't figure out, how to overload the [] operator for a referenced
object. if i have

class MyClass {

int operator[](int i) { return 1; };

};

....

MyClass* oskar = new MyClass();
cout << oskar[3];
delete oskar;

the compiler says "cannot convert ‘OperatorSequence’ to ‘int’ in
initialization". with

MyClass oskar;

it works, though. how can i use the overloaded [] for pointers? i also need
to overload arithmetic operations in my class, is there a similar problem
when dealing with referenced objects?

thanks in advance and greetings, jonas
 
R

Rolf Magnus

Jonas said:
hello,

somehow i can't figure out, how to overload the [] operator for a
referenced object. if i have

class MyClass {

int operator[](int i) { return 1; };

};

...

MyClass* oskar = new MyClass();
cout << oskar[3];
delete oskar;

the compiler says "cannot convert ‘OperatorSequence’ to ‘int’ in
initialization".

The compiler probably wants to say that it can't find an operator << that
takes a MyClass object. oskar[3] ist the same as *(oskar+3), expecting that
oskar is the pointer to the start of an array of MyClass, and you wan the
3rd element of that array.
with

MyClass oskar;

it works, though. how can i use the overloaded [] for pointers?

You are using it, but I guess you actually don't want to. If you want to use
the [] operator of your class instead of the one for pointers, you have to
dereference first:

cout << (*oskar)[3];
i also need to overload arithmetic operations in my class, is there a
similar problem when dealing with referenced objects?

Well, if you use a pointer, the operators for pointers will be used.
 
K

Kai-Uwe Bux

Jonas said:
hello,

somehow i can't figure out, how to overload the [] operator for a
referenced object. if i have

class MyClass {

int operator[](int i) { return 1; };

You might want to consider using std::size_t instead of int as the argument
type.
};

...

MyClass* oskar = new MyClass();
cout << oskar[3];

Two options:

oskar->operator[](3)

or (more readable):

(*oskar)[3]

delete oskar;

the compiler says "cannot convert ?OperatorSequence? to ?int? in
initialization". with

MyClass oskar;

it works, though. how can i use the overloaded [] for pointers? i also
need to overload arithmetic operations in my class, is there a similar
problem when dealing with referenced objects?

The problem is that you don't distinguish between the pointer and the
pointee. If you want to add the pointees, you have to get them first by
dereferencing the pointer. The problem is totally unrelated to your class,
you would face it with pointers of type int* just as well.


int* ap = new int ( 5 );
int* bp = new int ( 6 ); // warning: already possibly leaking ap.
ap + bp; // bogus: trying to add two pointers
*ap + *bp; // ok: adding pointees.
delete ap;
delete bp;


Best

Kai-Uwe Bux
 
R

red floyd

Jonas said:
hello,

somehow i can't figure out, how to overload the [] operator for a referenced
object. if i have

class MyClass {

int operator[](int i) { return 1; };

};

...

MyClass* oskar = new MyClass();
cout << oskar[3];
delete oskar;

the compiler says "cannot convert ‘OperatorSequence’ to ‘int’ in
initialization". with

MyClass oskar;

it works, though. how can i use the overloaded [] for pointers? i also need
to overload arithmetic operations in my class, is there a similar problem
when dealing with referenced objects?

thanks in advance and greetings, jonas
Because you're applying it to a pointer, not a reference or an object.

MyClass oskar;
cout << oskar[3];
 
J

John Harrison

Jonas said:
hello,

somehow i can't figure out, how to overload the [] operator for a referenced
object. if i have

class MyClass {

int operator[](int i) { return 1; };

};

...

MyClass* oskar = new MyClass();
cout << oskar[3];
delete oskar;

the compiler says "cannot convert ‘OperatorSequence’ to ‘int’ in
initialization". with

MyClass oskar;

it works, though. how can i use the overloaded [] for pointers? i also need
to overload arithmetic operations in my class, is there a similar problem
when dealing with referenced objects?

thanks in advance and greetings, jonas

You cannot overload operator[] for pointers, you cannot overload any
pointer operator.

It sounds like you want a class that overload several operators but
behaves like a pointer otherwise. Well, that is what you must write

class MyPtrClass
{
public:
int operator[](int i);
// etc...
private:
MyClass* ptr;
};

In other words write a class that contains a single pointer to another
class, and put the overloaded operators there.

john
 
S

Sylvester Hesp

Kai-Uwe Bux said:
Jonas said:
hello,

somehow i can't figure out, how to overload the [] operator for a
referenced object. if i have

class MyClass {

int operator[](int i) { return 1; };

You might want to consider using std::size_t instead of int as the
argument
type.

Yes you would think that, although in some cases this can lead to problems,
particularly when a conversion operator to another type that supports
operator[](int) exists (such as pointers). Say, for example, you have a
string class with a conversion operator to const char *

class String
{
public:
// yadda yadda yadda
char & operator[](size_t);
char operator[](size_t) const;

operator const char *() const;
};

void foo()
{
String s;
s[4]; // ambiguous call
}

s[4] wouldn't be ambiguous if String::eek:perator[] accepted int instead of
size_t, because the literal 4 is int, which either has to be promoted to
size_t for String::eek:perator[], or s has to be converted to const char* for
operator[](const char*, int). Now, if String::eek:perator[] accepted int,
you'll never have this problem (not even if you pass it size_t).

I think it's best to leave the argument to operator[]s for array-like
indexing as ints (or perhaps even better: ptrdiff_t) rather than as other
integral types, as that's how the standard defines it's built-in types.

- Sylvester
 
K

Kai-Uwe Bux

Sylvester said:
Kai-Uwe Bux said:
Jonas said:
hello,

somehow i can't figure out, how to overload the [] operator for a
referenced object. if i have

class MyClass {

int operator[](int i) { return 1; };

You might want to consider using std::size_t instead of int as the
argument
type.

Yes you would think that, although in some cases this can lead to
problems, particularly when a conversion operator to another type that
supports operator[](int) exists (such as pointers). Say, for example, you
have a string class with a conversion operator to const char *

class String
{
public:
// yadda yadda yadda
char & operator[](size_t);
char operator[](size_t) const;

operator const char *() const;
};

void foo()
{
String s;
s[4]; // ambiguous call
}

s[4] wouldn't be ambiguous if String::eek:perator[] accepted int instead of
size_t, because the literal 4 is int, which either has to be promoted to
size_t for String::eek:perator[], or s has to be converted to const char* for
operator[](const char*, int). Now, if String::eek:perator[] accepted int,
you'll never have this problem (not even if you pass it size_t).

I think it's best to leave the argument to operator[]s for array-like
indexing as ints (or perhaps even better: ptrdiff_t) rather than as other
integral types, as that's how the standard defines it's built-in types.

Well, I beg to differ. I agree that the example demonstrates a problem.
However, I would locate the problem in the example at a different position:
the conversion operator to char* should be made explicit, i.e., it should
be a member function like data() or c_str(). This is the precedent set by
the standard library. Generally, implicit conversions can lead to
surprises, and this is what your example demonstrates.

The standard library makes operator[] take size_type for container types and
difference_type for iterator types, which makes perfect sense. Note that
raw-pointers are more like iterators than containers. The class in you
example may suffer from not knowing what it wants to be. By and large, I
tend to follow the standard library in those questions. It makes my code
base more coherent.


Best

Kai-Uwe Bux
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top