[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

bashill.zhu@gmail.com

10/4/2008 1:04:00 PM

This is a program just for testing operator overloading. But I found
the operator ++ doesn't act like on built-in types. For detail:
When
int array[10];
Ptr_to_T<int> smart_ptr(&array[0], array, 10);
*smart_ptr++ = 10; // I want to modify array[0],but this sentence
modifies array[1]

Do I make myself clear?
Could some body tell me how to fix it ?

#include <iostream>
using namespace std;
template<typename T>
class Ptr_to_T
{
public:
Ptr_to_T(T* p, T* array, int size):_p(p),_array(array),_size(size)
{}
Ptr_to_T(T* p):_p(p){}
Ptr_to_T& operator++(){//prefix
_p += 1;
return *this;
}
Ptr_to_T& operator++(int){//postfix
cout << "Entering Operator++" << endl;
T* temp = _p;
_p += 1;
return *this;
}
T& operator*(){
cout << "Entering Operator*" << endl;
return *_p;
}
private:
T* _p;
T* _array;
int _size;
};
int main()
{
int array[10];
Ptr_to_T<int> smart_ptr(&array[0], array, 10);
*smart_ptr++ = 10;
cout << array[0] << endl;
cout << array[1] << endl;
}


Result:

Entering Operator++
Entering Operator*
4246640
10


8 Answers

Obnoxious User

10/4/2008 1:08:00 PM

0

On Sat, 04 Oct 2008 06:03:30 -0700, bashill.zhu@gmail.com wrote:

> This is a program just for testing operator overloading. But I found the
> operator ++ doesn't act like on built-in types. For detail: When
> int array[10];
> Ptr_to_T<int> smart_ptr(&array[0], array, 10); *smart_ptr++ = 10; //
> I want to modify array[0],but this sentence
> modifies array[1]
>
> Do I make myself clear?
> Could some body tell me how to fix it ?
>

http://www.cppreference.com/wiki/operator_...

--
OU
Remember 18th of June 2008, Democracy died that afternoon.
http://frapedia.se/wiki/Information_...

Obnoxious User

10/4/2008 1:14:00 PM

0

On Sat, 04 Oct 2008 06:03:30 -0700, bashill.zhu@gmail.com wrote:

> This is a program just for testing operator overloading. But I found the
> operator ++ doesn't act like on built-in types. For detail: When
> int array[10];
> Ptr_to_T<int> smart_ptr(&array[0], array, 10); *smart_ptr++ = 10; //
> I want to modify array[0],but this sentence
> modifies array[1]
>
> Do I make myself clear?
> Could some body tell me how to fix it ?

Ignore my first reply. I didn't look at the code close enough.

>
> #include <iostream>
> using namespace std;
> template<typename T>
> class Ptr_to_T
> {
> public:
> Ptr_to_T(T* p, T* array, int size):_p(p),_array(array),_size(size)
> {}
> Ptr_to_T(T* p):_p(p){}
> Ptr_to_T& operator++(){//prefix
> _p += 1;
> return *this;
> }
> Ptr_to_T& operator++(int){//postfix
> cout << "Entering Operator++" << endl; T* temp = _p;
> _p += 1;
> return *this;
> }

Ptr_to_T operator++(int){//postfix
cout << "Entering Operator++" << endl;
Ptr_to_T temp(*this);
_p += 1;
return temp;
}

--
OU
Remember 18th of June 2008, Democracy died that afternoon.
http://frapedia.se/wiki/Information_...

Pete Becker

10/4/2008 2:53:00 PM

0

On 2008-10-04 09:03:30 -0400, "bashill.zhu@gmail.com"
<bashill.zhu@gmail.com> said:

> Ptr_to_T& operator++(int){//postfix
> cout << "Entering Operator++" << endl;
> T* temp = _p;
> _p += 1;
> return *this;
> }

This operator increments *this then returns it. What it should do is
make a local copy of *this, increment *this, and return the local copy
by value. Typically, that looks like this:

my_iterator my_iterator::operator++(int)
{
my_iterator temp(*this);
++*this;
return temp;
}

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

bashill.zhu@gmail.com

10/6/2008 12:57:00 AM

0

On 10?4?, ??10?52?, Pete Becker <p...@versatilecoding.com> wrote:
> On 2008-10-04 09:03:30 -0400, "bashill....@gmail.com"
> <bashill....@gmail.com> said:
>
> > Ptr_to_T& operator++(int){//postfix
> > cout << "Entering Operator++" << endl;
> > T* temp = _p;
> > _p += 1;
> > return *this;
> > }
>
> This operator increments *this then returns it. What it should do is
> make a local copy of *this, increment *this, and return the local copy
> by value. Typically, that looks like this:
>
> my_iterator my_iterator::operator++(int)
> {
> my_iterator temp(*this);
> ++*this;
> return temp;
>
> }
>
> --
> Pete
> Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
> Standard C++ Library Extensions: a Tutorial and Reference
> (www.petebecker.com/tr1book)

Thanks all, Got it!

#include <iostream>
using namespace std;
template<typename T>
class Ptr_to_T
{
public:
class Range{};

Ptr_to_T(T* p, T* array, int size):_p(p),_array(array),_size(size)
{
}
Ptr_to_T(T* p):_p(p){}
Ptr_to_T& operator++(){//prefix
_p += 1;
return *this;
}
const Ptr_to_T operator++(int){//postfix
T* temp = _p;
_p += 1;
return Ptr_to_T(temp, temp, _array + _size - temp);
}
T& operator*(){
check();
return *_p;
}
private:
void check(){
if( _p - _array >= _size || _p < _array){
cout << _p - _array << endl;
throw Range();
}
}

T* _p;
T* _array;
int _size;
};

James Kanze

10/6/2008 12:31:00 PM

0

On Oct 4, 4:52 pm, Pete Becker <p...@versatilecoding.com> wrote:
> On 2008-10-04 09:03:30 -0400, "bashill....@gmail.com"
> <bashill....@gmail.com> said:

> > Ptr_to_T& operator++(int){//postfix
> > cout << "Entering Operator++" << endl;
> > T* temp = _p;
> > _p += 1;
> > return *this;
> > }

> This operator increments *this then returns it. What it should
> do is make a local copy of *this, increment *this, and return
> the local copy by value. Typically, that looks like this:

> my_iterator my_iterator::operator++(int)
> {
> my_iterator temp(*this);
> ++*this;
> return temp;
> }

This is, of course, the difference he was complaining about, but
there is another significant difference: the built-in operator++
requires an lvalue; this overload doesn't. If you really want
to be as close as possible to the built-in types (and think that
it makes a difference), you should define the operator as a
non-member, taking a non-const reference.

Of course, even then, it introduces sequence points which aren't
present with a built-in operator:-).

(Seriously, the rule of making a user defined operator behave as
closely as possible to what the built-in operator does is really
only applicable in cases where the built-in operator would be
usable. Trapping accidental use where the built-in operator
would cause an error is a lot less important.)

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Hendrik Schober

10/6/2008 3:49:00 PM

0

James Kanze wrote:
> [...] If you really want
> to be as close as possible to the built-in types (and think that
> it makes a difference), you should define the operator as a
> non-member, taking a non-const reference.

What's the difference (besides the different syntax to call
those functions) between
struct X { void f(); };
and
struct X {}; void g(Y&);
?

> [...]

Schobi

James Kanze

10/7/2008 10:00:00 AM

0

On Oct 6, 5:48 pm, Hendrik Schober <spamt...@gmx.de> wrote:
> James Kanze wrote:
> > [...] If you really want
> > to be as close as possible to the built-in types (and think that
> > it makes a difference), you should define the operator as a
> > non-member, taking a non-const reference.

> What's the difference (besides the different syntax to call
> those functions) between
> struct X { void f(); };
> and
> struct X {}; void g(Y&);
> ?

The first can be called on a temporary, the second can't; i.e.:

X().f() ; // legal
g( X() ) ; // illegal

In the case of an overloaded operator, of course, the syntax for
the two calls is the same, e.g. ++X(); if the operator++()
function is a member, it's legal, if it is a free function
taking a non-const reference (which is the only way it could be
a free function), it's not.

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Hendrik Schober

10/7/2008 11:00:00 AM

0

James Kanze wrote:
> On Oct 6, 5:48 pm, Hendrik Schober <spamt...@gmx.de> wrote:
>> James Kanze wrote:
>>> [...] If you really want
>>> to be as close as possible to the built-in types (and think that
>>> it makes a difference), you should define the operator as a
>>> non-member, taking a non-const reference.
>
>> What's the difference (besides the different syntax to call
>> those functions) between
>> struct X { void f(); };
>> and
>> struct X {}; void g(Y&);
>> ?
>
> The first can be called on a temporary, the second can't; [...]

Ah, right. I forgot about this.

> In the case of an overloaded operator, of course, the syntax for
> the two calls is the same, e.g. ++X(); if the operator++()
> function is a member, it's legal, if it is a free function
> taking a non-const reference (which is the only way it could be
> a free function), it's not.

What I thought is that, if 'operator++()' actually changes
its argument (as it is supposed to do), and if it's applied
to a temporary, then this means that an rvalue is changed --
which I thought is UB.
I suppose I'm wrong?

Schobi