C++ 静态成员变量能否调用非静态成员函数?

C++ 静态成员变量能否调用非静态成员函数?,c++,C++,我看到了以下代码: 我知道如果我错了,请纠正我 静态函数只能访问写/读静态成员变量 非静态函数可以访问写/读静态成员变量 基于上述示例,似乎静态变量可以访问非静态函数。 这是否正确?实例,顾名思义,返回指向实例的指针。它还使用静态实例指针字段s_instance。这是静态的,这意味着每个类只有一个s_实例字段。一旦从实例中获得该实例指针,就可以像使用任何其他实例指针一样使用它。您通过静态方法获得它的事实,以及该方法使用静态字段的事实,都是无关的 静态方法本身是有效的;它不会隐式或显式地使用它。

我看到了以下代码:

我知道如果我错了,请纠正我

静态函数只能访问写/读静态成员变量

非静态函数可以访问写/读静态成员变量

基于上述示例,似乎静态变量可以访问非静态函数。 这是否正确?

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

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

变量不会调用任何东西

这并没有真正解决示例代码,但它纠正了代码下面列出的两条规则中的一个错误概念

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

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

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

你的代码和你刚才说的不完全一样

为了理解它在做什么,让我们后退一点,谈谈类的真正含义。类定义新类型。另一种类型是int。int的实例可以位于函数本地变量或参数中,它可以通过调用新int存储在堆上,也可以通过在文件范围中声明一个int来全局。它们都不知道或关心存储在哪里,但它们都是int类型的实例

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

类还可以做一些不属于定义其实例的数据和行为的事情,这些是类的静态成员

由于这些概念从根本上是分离的,它们实际上并不相互干扰。事实上,您可以让该类的一个静态成员引用该类的一个实例,这正是singleton模式的示例所做的

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


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

技术问题已在其他答案中公布,我将仅添加一个示例,试图帮助消除混淆。假设您创建了一个类Human来表示一个人,它可以具有诸如眼睛颜色、名称等属性。。。以及定义行走、跳跃等动作的方法。。。这些属性和方法对于人类的每个实例都是特定的:一个特定的人类可能有一双蓝眼睛,你可以让她说话

在另一个层次上,可能有一些属性或行为不是特定于实例的,而是整个人类类别的,比如谁是最高的或最年长的人类。这些被宣布为静态的,属于整个人类,而不是每个人


现在,一旦你从班级里得到一个人,比如说最高的,这个人是人,因此你可以要求任何你想要的财产,或者你可以请求任何你需要的动作:Human::get\u highter.get\u something\u from\u coupboard将请求最高的get\u higher Human在集合集体行动中,然后请求特定的个人为你执行一个动作get\u something\u from\u coupboard,这是一个由特定实例执行的动作。

Hello MacGuy,实例返回s_实例,它是一个静态成员变量。所以我假设这个函数返回一个静态成员变量。我说的对吗感谢you@q0987-是的,没错。静态方法不能访问非静态方法,但实例(静态或其他)可以访问这两种方法。@Phil,这是我感到困惑的地方。因为返回的实例是一个静态变量。该静态变量如何调用非静态成员函数set_值并更改非静态成员变量m_值?换句话说,静态
变量决定使用哪个“this”?-再次感谢,变量没有调用任何东西。foo函数正在调用非静态成员函数,这需要一个实例。有一个实例,它来自GlobalClass::instance。此外,GlobalClass::instance不返回s_实例,它返回它的一个副本一个指针的副本是指向同一地址的另一个指针。@q0987-方法实例上的修饰符static表示不需要GlobalClass实例来调用它。s_实例上的修饰符static表示只有一个,并且所有实例都共享它。这里的static描述了类如何使用它。但归根结底,它仍然是类本身的一个实例。和实例可以访问静态和非静态方法。静态成员函数不能访问非静态成员变量。@q0987:可以。我可以给你举个例子,但我真的希望你先停下来想想我的答案。学习思考软件是学习编程的一个非常重要的部分。我同意q0987:静态成员函数只能使用静态数据成员。您在示例Ben Voigt中展示的是,实例可以访问非静态数据成员。比我所能管理的更简洁。我想他也混淆了s_实例本身是静态的,而不仅仅是获取指针的方法。
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';
}