开发者

Can a static member variable call non-static member functions?

I saw the following code:

http://sourcemaking.com/design_patterns/singleton/cpp/1

class GlobalClass
{
private:
    int m_value;
开发者_如何学Python    static GlobalClass *s_instance;
    GlobalClass(int v = 0)
    {
        m_value = v;
    }
public:
    int get_value()
    {
        return m_value;
    }
    void set_value(int v)
    {
        m_value = v;
    }
    static GlobalClass *instance()
    {
        if (!s_instance)
            s_instance = new GlobalClass;
        return s_instance;
    }
};

GlobalClass *GlobalClass::s_instance = 0;

void foo(void)
{
    GlobalClass::instance()->set_value(1); // static variable calls non-static functions
    cout << "foo: global_ptr is " << GlobalClass::instance()->get_value() << '\n';
}

As I know (please correct me if I am wrong here),

  1. Static functions can only access(write/read) static member variables

  2. Non-Static functions can access(write/read) static member variables

Based on above sample, it seems that a static variable can access non-static functions.

Is this correct?


Variables don't call anything

(This doesn't really address the sample code, but it corrects a misconception in the two "rules" listed beneath the code)

A static member function is a member, and can access all public, protected, and private members of its class, both static and instance.

However, static member functions have no this pointer, so to access an instance member, the instance needs to be specified.


it seems that a static variable can access non-static functions.

the code you have doesn't do quite what you just said.

To understand what it's doing, lets back up a bit and talk about what class really means. classes define new types. another type is int. an instance of an int can be located in a functions local variables or parameters, it can be stored on the heap by calling new int, it can be global by declaring one at the file scope. none of them know or care where they are stored, but they are all instances of the type int.

When you make an instance of a class, you are creating the space used and the behaviors on the instance of that class, and those behaviors apply to every instance equally.

classes can also do something that isn't part of defining the data and behaviors of its instances, and those are the static members of the class.

Since these concepts are fundamentally separate, they don't really interfere with each other. in fact, you could have one of the static members of the class refer to an instance of the class, and that's exactly what this example of the singleton pattern does.

So what's actually happening, from the very beginning is you are creating an instance of the class, using new GlobalClass, and then keeping the pointer someplace. It happens that the pointer is being saved as a static member of the same class that defines the type of the instance you just created.

then GlobalClass provides a mechanism to use that instance. when you invoke GlobalClass::instance(), it reads a static class variable, which is allowed. the variable holds a pointer, which when dereferenced (via ->) results in the one object we created earlier, and that object, since it is an instance of GlobalClass, is now allowed to access an instance variable.


instance, as its name suggests, returns a pointer to an instance. It also uses a static instance pointer field, s_instance. The fact that this is static means that there is only one s_instance field per class. Once you get that instance pointer (from instance), you can use it like any other instance pointer. The facts that you got it via a static method, and that the method uses a static field, are irrelevant.

The static method itself is valid; it doesn't use this implicitly or explicitly.


The technical issues have already been posted in other answers, I will just add an example trying to help with the confusion. Imagine that you create a class Human to represent a human being, it can have properties like the color of the eyes, the name and such... and methods that define the actions like walk, jump... those properties and methods are particular to each instance of Human: a particular human might have blue eyes, and you can ask her to talk.

In a different level, there might be properties or actions that are not particular to the instance but rather to the whole class of Humans, like who is the tallest or the eldest human. Those are declared static as belonging to the whole set of humans, rather than to each individual.

Now, once you obtain an individual from the class, say the tallest, that individual is a Human, and as such you can request any property you want, or you can request any action you need: Human::get_tallest().get_something_from_cupboard() will request the tallest (get_tallest()) Human in the set (class action) and then request that particular individual to perform an action for you (get_something_from_cupboard()) which is an action performed by a particular instance.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜