Handmade Hero » Forums » Code » HELP: How the STL handles the member access operator (. or ->)???
itzjac
16 posts
#16643 HELP: How the STL handles the member access operator (. or ->)???
3 weeks, 1 day ago Edited by itzjac on Oct. 29, 2018, 9:04 p.m. Reason: Initial post

Hello!

I stumble across my programming books, this reminded me that I have saved one particular book that showed how the STL works behind the scenes when using the member access operator (. or ->), it was something like this

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class A
{
public:
    void foo(float value) { /*something cool with the value */ }
};

int main()
{
    A theA;
    A::foo(theA, 10.f);
}


but I forgot about this particular book!

I am pretty sure there was a *this* keyword involved in that call.
Or maybe you can point me to the right STL file that handles those operators, then I can take a look myself.

Maybe another handmade hero can elaborate about this, and possibly know about that C++ book am talking about.

Kind regards
mmozeiko
Mārtiņš Možeiko
1826 posts / 1 project
#16644 HELP: How the STL handles the member access operator (. or ->)???
3 weeks, 1 day ago Edited by Mārtiņš Možeiko on Oct. 29, 2018, 9:29 p.m.

I'm not sure what you want to show in your code or what book are you talking about.
But STL simply overloads -> operator for iterators.

Here is a very basic example:
 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 <stdio.h>

struct Apple
{
  float weight;

  void print()
  {
    printf("weight = %f\n", weight);
  }
};

struct AppleIterator
{
  AppleIterator(Apple* apple) : apple(apple) {}
  AppleIterator& operator ++ () { apple++; return *this; }
  Apple* operator -> () { return apple; }
  bool operator == (const AppleIterator& other) { return apple == other.apple; }
  bool operator != (const AppleIterator& other) { return !(*this == other); }
private:
  Apple* apple;
};

struct Basket
{
  Basket() { for (int i=0; i<10; i++) apples[i].weight = i; }
  AppleIterator begin() { return AppleIterator(apples); }
  AppleIterator end() { return AppleIterator(apples + 10); }
private:
  Apple apples[10];
};

int main()
{
  Basket b;
  for (auto it = b.begin(); it != b.end(); ++it)
  {
    it->print();
  }
}


Of course real iterators have much more code for them to be functional. Like operator *, or postincrement opreator, also decrement operators, and more...

If it is not clear what code is doing, open it in debugger and do the stepping (step into) over the execution of program and see how it gets to printf function.
itzjac
16 posts
#16646 HELP: How the STL handles the member access operator (. or ->)???
3 weeks, 1 day ago

Thank you.

Am familiar with that code and also stepping into the code with the debugger, but...


I think the approach described in the book, referred to how one would build up classes using simple C structs, and the syntax was probably not a real STL solution, but it definitely described a good way to implement this.
rationalcoder
Blake Martin
2 posts
#16794 HELP: How the STL handles the member access operator (. or ->)???
4 days, 20 hours ago

I think I know what you are referring too.
 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
struct A
{
    int data1;
    int data1;

    void (*foo)(A* this_, float value);
};

void
A_foo(A* this_, float value)
{
    // stuff
}

void
A_init(A* this_, int data1, int data2)
{
    this_->data1 = data1;
    this_->data1 = data1;
    this_->foo   = A_foo;
}

int main()
{
    A obj;
    A_init(&obj);
    obj->foo(&A);

    return 0;
}


The difference is that in C++, member function pointers aren't stored in the class, they are simply called at the correct time.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
class Object
{
public:
    Object() {}
    int foo(float value) { return (int)value; }

private:
    int data;
};

int main()
{
    Object o;
    int i = o.foo(0);
    return 0;
}


can be though of generating this C 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
struct Object
{
    int data;
};

void
Object_ctor(Object* this)
{
    this->data = 0;
}

int
Object_foo(Object* this, float value)
{
    return (int)value;
}

int main()
{
    Object o;
    Object_ctor(&o);
    int i = Object_foo(&o, 0);

    return 0;
    // no Object_dtor(&o) in this case (or maybe one that sets value to zero, I can't remember)
}