静态成员变量可以调用非静态成员函数吗?
我看到下面的代码:
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';
}
据我所知(请纠正我,如果我错了这里),
静态函数只能访问(读/写)静态成员变量
非静态函数可以访问(写入/读取)静态成员变量
基于上面的示例,似乎静态变量可以访问非静态函数。
这是正确的吗?
变量不叫什么
(这并没有真正解决示例代码,但它的两个“规则”的代码下面列出的纠正一个误解)
静态成员函数是一个成员,并且可以访问其类的所有公共,受保护和私有成员,包括静态和实例。
但是,静态成员函数没有this
指针,因此要访问实例成员,需要指定实例。
instance
顾名思义就是返回一个指向实例的指针。它也使用静态实例指针字段s_instance
。这是静态的这一事实意味着每个类只有一个s_instance
字段。一旦获得该实例指针(来自instance
),就可以像使用其他实例指针一样使用它。您通过静态方法获得的事实,并且该方法使用静态字段是无关紧要的。
静态方法本身是有效的;它不会隐式或显式使用this
。
比我能管理的更简洁。我认为他也感到困惑,s_instance本身是静态的,而不仅仅是他得到指针的方法。 – Phil 2010-11-09 07:52:11
@菲尔,好点。我添加了一些关于该领域的讨论。 – 2010-11-09 15:58:12
看来,一个静态变量可以访问非静态函数。
你的代码并不完全符合你刚才所说的。
为了理解它在做什么,让我们回过头来谈谈class
的真正含义。类定义新类型。另一种类型是int
。一个int实例可以位于函数局部变量或参数中,它可以通过调用new int
存储在堆上,它可以是全局的,只需在文件范围内声明一个即可。他们都不知道或不在乎他们的存储位置,但他们都是int
类型的实例。
当您创建class
的实例时,您正在创建所使用的空间以及该类实例上的行为,并且这些行为同样适用于每个实例。
类也可以做一些不是定义其实例的数据和行为的一部分,而这些是类的静态成员。
由于这些概念基本上是分开的,所以它们并不真正互相干扰。实际上,您可以让该类的静态成员之一引用该类的一个实例,而这正是单例模式的例子。
所以实际上发生了什么,从一开始就是创建一个类的实例,使用new GlobalClass
,然后将指针保持在某个位置。碰巧指针被保存为定义刚刚创建的实例类型的同一类的静态成员。
然后GlobalClass
提供了使用该实例的机制。当你调用GlobalClass::instance()
时,它会读取一个允许的静态类变量。该变量包含一个指针,该指针在解除引用时(通过->
)会导致我们先前创建的一个对象,并且该对象因为它是GlobalClass的一个实例,现在允许访问实例变量。
Hello TokenMacGuy,GlobalClass :: instance()返回s_instance,它是一个静态成员变量。所以我假设这个函数返回一个静态成员变量。我对么? - 谢谢 – q0987 2010-11-09 04:44:01
@ q0987 - 是的,这是正确的。静态方法不能访问非静态方法,但是一个实例(静态或其他)可以访问两者。 – Phil 2010-11-09 04:49:02
@菲尔,这是我感到困惑的一点。由于返回的实例是一个静态变量。这个静态变量如何调用非静态成员函数set_value并更改非静态成员变量m_value?换句话说,一个静态变量如何确定使用哪个“this”? - 谢谢 – q0987 2010-11-09 04:57:03
技术问题已经发布在其他答案中,我只是添加一个试图帮助解决混乱的例子。想象一下,你创建了一个Human类来表示一个人,它可以拥有诸如眼睛的颜色,名称等等的属性以及定义诸如步行,跳跃等动作的方法......这些属性和方法是特定的给人类的每个实例:一个特定的人可能有蓝眼睛,你可以让她说话。
在不同的层次上,可能会有不属于实例的特性或行为,而是涉及到整个人类,比如谁是最高或最高级的人类。那些被宣称为静态属于整个人类,而不是每个人。
现在,一旦你从班上获得一个人,说最高,那个人是一个人,因此你可以要求任何你想要的财产,或者你可以要求你需要的任何行动:Human::get_tallest().get_something_from_cupboard()
将要求最高(get_tallest()
)集体中的人(集体诉讼),然后请求特定的个人为您执行某项操作(get_something_from_cupboard()
),这是由特定的实例执行的操作。
静态成员函数不能访问非静态成员变量。 – q0987 2010-11-09 04:48:54
@ q0987:是的,它可以。我可以给你一个例子,但我真的希望你停下来,首先想想我的答案。学习思考软件是学习编程非常重要的一部分。 – 2010-11-09 05:05:30
以下是您的示例:http://ideone.com/gX5wF – 2010-11-09 05:10:43