繁体   English   中英

静态成员变量可以调用非静态成员函数吗?

[英]Can a static member variable call non-static member functions?

我看到了以下代码:
http://sourcemaking.com/design_patterns/singleton/cpp/1

class GlobalClass
{
private:
    int m_value;
    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';
}

据我所知(如果我错了,请纠正我),

  1. 静态函数只能访问(写入/读取)静态成员变量

  2. 非静态函数可以访问(写入/读取)静态成员变量

根据以上示例,似乎静态变量可以访问非静态函数。
这个对吗?

变量什么也没叫

(这并没有真正解决示例代码,但是它纠正了代码下方列出的两个“规则”中的误解)

静态成员函数是成员,并且可以访问其类的所有公共成员,受保护成员和私有成员,包括静态成员和实例成员。

但是,静态成员函数没有this指针,因此要访问实例成员,需要指定实例。

似乎静态变量可以访问非静态函数。

您拥有的代码与您刚才所说的不一样。

要了解它的作用,请先备份一下并讨论class真正含义。 类定义新的类型。 另一种类型是int 一个int的实例可以位于函数的局部变量或参数中,可以通过调用new int来存储在堆中,可以通过在文件范围内声明一个new int来实现全局。 它们都不知道或不在乎它们的存储位置,但是它们都是int类型的实例。

当创建一个class的实例时,您将在class的实例上创建使用的空间和行为,并且这些行为同样适用于每个实例。

类还可以执行某些操作,这些操作不是定义其实例的数据和行为的一部分,而这些是类的静态成员。

由于这些概念从根本上是分开的,因此它们实际上并没有相互干扰。 实际上,您可以让该类的静态成员之一引用该类的实例,而这正是单例模式的示例所做的。

因此,实际上是从一开始就在使用new GlobalClass创建类的实例,然后将指针保留在某个地方。 碰巧该指针被保存为同一类的静态成员,该类定义了您刚创建的实例的类型。

然后GlobalClass提供一种使用该实例的机制。 当您调用GlobalClass::instance() ,它将读取一个允许的静态类变量。 变量包含一个指针,当该指针被取消引用时(通过-> ),该指针将导致我们先前创建的一个对象,并且由于该对象是GlobalClass的实例,因此现在可以访问该实例变量。

instance ,顾名思义,返回一个指向一个实例。 它还使用静态实例指针字段s_instance 这是静态的事实意味着每个类只有一个s_instance字段。 一旦(从instance )获得了该实例指针,就可以像使用任何其他实例指针一样使用它。 通过静态方法获得的信息以及该方法使用静态字段的事实是无关紧要的。

静态方法本身是有效的; 它不会隐式或显式地使用this

技术问题已经在其他答案中发布,我将仅添加一个示例来尝试解决混乱问题。 想象一下,您创建了一个人类类来代表人类,它可以具有诸如眼睛的颜色,名称等之类的属性...以及定义诸如步行,跳跃之类的动作的方法...这些属性和方法是特别的每个人类实例 :一个特定的人类可能有蓝眼睛,您可以请她讲话。

在不同的级别上,可能存在并非特定于实例而是特定于整个人类类的属性或动作,例如谁是最高或最高的人类。 这些被声明为静态的,因为它属于整个人类,而不是每个人。

现在,一旦您从班级中获得了一个最高的人,即该人就是人类,因此您可以请求所需的任何属性,也可以请求所需的任何操作: Human::get_tallest().get_something_from_cupboard()将请求get_tallest()最高的( get_tallest() )人(类动作),然后请求特定个人为您执行动作( get_something_from_cupboard() ),这是由特定实例执行的动作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM