I was reading about static member functions when I met the following
interesting piece of code:
#include <iostream>
using namespace std;
class Egg {
private:
static Egg e;
int i;
Egg(int ii) : i(ii) {}
Egg(const Egg&); // Prevent copy-construction
public:
static Egg* instance() { return &e; } //<--- THIS IS WHAT INTERESTS
ME
int val() const { return i; }
};
Egg Egg::e(47);
int main() {
cout << Egg::instance()->val() << endl; //<--- THIS IS TOO
}
It's interesting, because the function "instance()", as it returns an
Egg pointer/address, is pointing to (in main) the member function "val
()" -- which returns an int. It seems to me the "instance()" member
function works like a pointer of type Egg. Am I right?
I would appreciate any further clarifications/explanations.
Thank You!
Marcelo de Brito
> class Egg {
> private:
> static Egg e;
[...]
> static Egg* instance() { return &e; } //<--- THIS IS WHAT INTERESTS
> ME
The instance member function returns the address of the static member
e.
> cout << Egg::instance()->val() << endl; //<--- THIS IS TOO
> It's interesting, because the function "instance()", as it returns an
> Egg pointer/address,
Correct.
> is pointing to (in main) the member function "val
> ()" -- which returns an int.
That's not correct. The Egg* that instance() returns "is pointing to
e". It is not pointing to a member function.
> It seems to me the "instance()" member
> function works like a pointer of type Egg. Am I right?
You are right on that one.
> I would appreciate any further clarifications/explanations.
Would this make it clearer:
Egg * p = Egg::instance();
p->val();
That's the equivalent of what you have above:
Egg::instance()->val()
Maybe you confuse -> operator as "pointing to"? Possibly because it
looks like an arrow? If so, no, -> operator "dereferences" the pointer
on it's left hand side.
So, when you say
p->val();
you mean "call the val() member of what p points to." Or more simply:
SomeType p = /* ... */
p->i = 42;
The last statement says "assign 42 to the 'i' member of the object
that 'p' points to."
Ali
> Hi!
>
> I was reading about static member functions when I met the following
> interesting piece of code:
>
> #include <iostream>
> using namespace std;
>
> class Egg {
> private:
> static Egg e;
Here you declare there is a static instance of Egg class, called e.
> int i;
> Egg(int ii) : i(ii) {}
> Egg(const Egg&); // Prevent copy-construction
> public:
> static Egg* instance() { return &e; } //<--- THIS IS WHAT INTERESTS
Here you return a pointer to this instance.
> ME
> int val() const { return i; }
> };
>
> Egg Egg::e(47);
Here the static instance e is defined (incl. memory allocation and
initialization).
>
> int main() {
> cout << Egg::instance()->val() << endl; //<--- THIS IS TOO
Here you use this pointer for calling val() on the e object. val()
returns an int which is passed to the cout via the relevant operator<<.
> }
>
> It's interesting, because the function "instance()", as it returns an
> Egg pointer/address, is pointing to (in main) the member function "val
> ()" -- which returns an int. It seems to me the "instance()" member
> function works like a pointer of type Egg. Am I right?
It returns a pointer to a single static object of that type, namely e.
>
> I would appreciate any further clarifications/explanations.
It seems you have troubles with the static data members, look them up in
your textbook. The static data objects have a couple of problems, namely
regarding their multi-threading behavior and also the order of
initialization, so they should be used with caution. In this example it
is also not clear why a pointer is returned from instance(); a reference
would serve better here IMO.
Paavo
Thank you very much, Ali and Paavo! :)
Ali, you are right. I should have expressed me more clearly concerning
C++ dereferencing. :)
Let me ask you an extra question.
From what Ali wrote above:
Here "p" is pointing to the address returned by "instance()" (you
assign the address returned by "instance()" to "p"):
Egg * p = Egg::instance();
And now you dereference/access it:
p->val();
Correct? :)
> Hi!
>
> Thank you very much, Ali and Paavo! :)
>
> Ali, you are right. I should have expressed me more clearly concerning
> C++ dereferencing. :)
>
> Let me ask you an extra question.
>
> From what Ali wrote above:
>
> Here "p" is pointing to the address returned by "instance()"
Not exactly, p *is* the address, not pointing to one.
(you
> assign the address returned by "instance()" to "p"):
Right.
>
> Egg * p = Egg::instance();
>
> And now you dereference/access it:
>
> p->val();
>
> Correct? :)
Yes, the -> operator dereferences the pointer, and during this operation
the value of p is certainly accessed (what is "access" is not so clear in
the C++ standard, but using the pointer value for dereferencing it should
certainly qualify).
Paavo
Thank you, Paavo! :)
Now I have a more clarifying conception of dereferencing in C++!
Best Wishes!
Marcelo de Brito