[C++] operator-> overloaden

Pagina: 1
Acties:

  • ^Mo^
  • Registratie: Januari 2001
  • Laatst online: 04-11-2025
Hoi,

Ik probeer in een programma hier de operator-> te overloaden, maar het wil niet werken als de instantie van het object al een pointer is. Klein voorbeeld:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class A
{
public:
    int i;

    A *operator->()
    {
        std::cout << "Operator-> called" << std::endl;
        return this;
    }
};

int main( int argc, char *argv[])
{
    A *p = new A();
    A a;
        
    p->i = 0;   // Doesn't work with the overloaded operator
    a->i = 0;   // Uses operator->()

    std::cin.get();

    return 0;
}

In dit voorbeeld krijg ik alleen de melding in het tweede geval, als de instantie dus op de stack staat. Is er een manier om dit voor alle situaties werkend te krijgen?

-Edit-
Ik compileer dit trouwens met zowel Visual C++ 6.0 als Visual C++ .NET 2003

[ Voor 11% gewijzigd door ^Mo^ op 04-11-2005 11:36 ]

"There are 10 kinds of people in the world, those who understand binary and those who don't" | Werkbak specs


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:30

.oisyn

Moderator Devschuur®

Demotivational Speaker

Natuurlijk niet, alle voor T gedefinieerde operators werken op een T. Een T* is simpelweg geen T, en gelukkig kun je voor primitive types (dus ook pointers) geen operators overloaden.

Ik snap ook niet waarom je dat zou willen, hoe kom je anders ooit bij de i van een A* als je operator-> geen this returnt? En je kunt natuurlijk regel 18 in jouw code vervangen door
C++:
1
2
3
4
5
(*p)->i = 0;

// of:
A & aRef = *p;
aRef->i = 0;

[ Voor 21% gewijzigd door .oisyn op 04-11-2005 11:50 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • ^Mo^
  • Registratie: Januari 2001
  • Laatst online: 04-11-2025
.oisyn schreef op vrijdag 04 november 2005 @ 11:48:
Natuurlijk niet, alle voor T gedefinieerde operators werken op een T. Een T* is simpelweg geen T, en gelukkig kun je voor primitive types (dus ook pointers) geen operators overloaden.

Ik snap ook niet waarom je dat zou willen, hoe kom je anders ooit bij de i van een A* als je operator-> geen this returnt? En je kunt natuurlijk regel 18 in jouw code vervangen door
C++:
1
2
3
4
5
(*p)->i = 0;

// of:
A & aRef = *p;
aRef->i = 0;
Een van onze klanten heeft een probleem met onze software, we hebben alleen geen idee waar (tenminste, niet 100%). We hebben echter wel een potentiele kanidaat, maar dit loopt allemaal via pointers. En we wilden dus wat debug regeltjes inbouwen om zeker te weten dat al deze pointers geldig blijven.

Het is inderdaad logisch dat het niet werkt, helemaal niet bij stil gestaan. Zal ik denk ik toch alles langs moeten lopen :/ Nou ja, als dat werkt, best...

"There are 10 kinds of people in the world, those who understand binary and those who don't" | Werkbak specs


  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

C++:
1
2
3
p->i
is equivalent met
(*p).i

maw als je iets wil overloaden is het de . operator, maar voor zover ik weet kan dat niet.

ASSUME makes an ASS out of U and ME


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:30

.oisyn

Moderator Devschuur®

Demotivational Speaker

_Mo_ schreef op vrijdag 04 november 2005 @ 12:00:
[...]

Een van onze klanten heeft een probleem met onze software, we hebben alleen geen idee waar (tenminste, niet 100%). We hebben echter wel een potentiele kanidaat, maar dit loopt allemaal via pointers. En we wilden dus wat debug regeltjes inbouwen om zeker te weten dat al deze pointers geldig blijven.
Dan pak je het verkeerd aan :). Je moet een type maken dat een pointer simuleert, juist door de -> te overloaden. In plaats van een A* gebruikt men dan bijvoorbeeld een APtr (wat geen pointer is). Je zou evt. nog de & operator op A kunnen overloaden zodat ie zo'n APtr returnt ipv de A* die by default gereturnd wordt. En natuurlijk niet vergeten de * operator op APtr ook te overloaden zodat je weer een A& krijgt ;)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • ^Mo^
  • Registratie: Januari 2001
  • Laatst online: 04-11-2025
.oisyn schreef op vrijdag 04 november 2005 @ 12:10:
[...]


Dan pak je het verkeerd aan :). Je moet een type maken dat een pointer simuleert, juist door de -> te overloaden. In plaats van een A* gebruikt men dan bijvoorbeeld een APtr (wat geen pointer is). Je zou evt. nog de & operator op A kunnen overloaden zodat ie zo'n APtr returnt ipv de A* die by default gereturnd wordt. En natuurlijk niet vergeten de * operator op APtr ook te overloaden zodat je weer een A& krijgt ;)
Aan zo'n soort constructie zat ik ook al te denken. Maar dat is denk ik niet echt haalbaar, want dat wordt nog meer werk dan eerst de pointer te dereferencen. Ik ga nog wel even prutsen en kijken of er nog andere opties zijn.

Bedankt in ieder geval :)

"There are 10 kinds of people in the world, those who understand binary and those who don't" | Werkbak specs


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 25-04 21:17

curry684

left part of the evil twins

.oisyn schreef op vrijdag 04 november 2005 @ 12:10:
[...]

Je zou evt. nog de & operator op A kunnen overloaden zodat ie zo'n APtr returnt ipv de A* die by default gereturnd wordt.
Op dat moment ben je designtechnisch de verantwoordelijkheid voor het functioneren van een utility class in de main class aan het leggen, en da's natuurlijk foute boel. Correct is om dit af te vangen door APtr een operator=(A*) en eenzelfde constructor te geven, en vervolgens de conversion operator A* te implementeren op je smart pointer.

Professionele website nodig?


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:30

.oisyn

Moderator Devschuur®

Demotivational Speaker

curry684 schreef op vrijdag 04 november 2005 @ 12:55:
[...]

Op dat moment ben je designtechnisch de verantwoordelijkheid voor het functioneren van een utility class in de main class aan het leggen, en da's natuurlijk foute boel.
De hele code moet toch veranderd worden als de pointer class gebruikt moet worden. En als je die APtr een typedef maakt afhankelijk van je buildsettings (zodat het een A* is in release bijvoorbeeld) maakt het geen zak uit.
Correct is om dit af te vangen door APtr een operator=(const A &) en eenzelfde constructor te geven
Que? Een pointer constructen uit een const reference? Dàn ben je pas designtechnisch fout bezig :). En uiteraard moet de pointer class gewoon een operator=(A *) en gelijke constructor hebben, maar dat is inherent aan het feit dat het een pointer class is.

[ Voor 13% gewijzigd door .oisyn op 04-11-2005 13:21 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 25-04 21:17

curry684

left part of the evil twins

Erm ja, die const hoorde daar niet :P

Professionele website nodig?


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:30

.oisyn

Moderator Devschuur®

Demotivational Speaker

Afgezien van dat, je moet een pointer niet kunnen constructen uit een non-pointer, dat gaat tegen het hele design van C++ in. Dit kan toch ook niet:
C++:
1
2
A a;
A * aPtr = a;


Als je een pointer class maakt moet je 'm ook laten gedragen als een pointer, imho :)


Daarnaast hoef je een operator& niet per se in je A class te definieren, het mag ook als losse functie :). Dus dan hoef je de definitie A niet eens aan te passen

[ Voor 25% gewijzigd door .oisyn op 04-11-2005 13:30 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 25-04 21:17

curry684

left part of the evil twins

Ja die signature die ik gaf klopte voor geen meter :P Het gaat natuurlijk om operator=(A*) zodat je de & op A niet hoeft te overloaden om APtr terug te geven maar je gewoon native de pointereigenschappen die je met &A introduceert kunt behouden :) Dat was het hele punt van het betoog eilijk 8)7

* curry684 te kort geslapen vannacht en al te lang geen C++ meer gedaan :'(

[ Voor 7% gewijzigd door curry684 op 04-11-2005 13:31 ]

Professionele website nodig?


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
De aanname dat je een A::operator& wil hebben die een APtr terug geeft is best redelijk:
C++:
1
2
3
4
5
6
7
template<typename Ptr>
void foo(Ptr p)
{
  std::cout << *p;
}
A a;
foo(&a);

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein

Pagina: 1