我看到以下代码:
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';
}
据我所知(如果我错了,请纠正我),
静态函数只能访问(写/读)静态成员变量
非静态函数可以访问(写入/读取)静态成员变量
基于上面的示例,似乎静态变量可以访问非静态函数 这是对的吗?
答案 0 :(得分:5)
变量不会调用任何内容
(这并没有真正解决示例代码,但它纠正了代码下面列出的两个“规则”中的误解)
静态成员函数是一个成员,可以访问其类的所有public,protected和private成员,包括static和instance。
但是,静态成员函数没有this
指针,因此要访问实例成员,需要指定实例。
答案 1 :(得分:4)
似乎静态变量可以访问非静态函数。
你所拥有的代码并没有完全按照你刚才所说的去做。
要了解它正在做什么,请稍微补充一下,然后讨论class
的真正含义。类定义新类型。另一种类型是int
。一个int的实例可以位于函数局部变量或参数中,它可以通过调用new int
存储在堆上,它可以通过在文件范围内声明一个来实现全局。他们都不知道或关心它们存储的位置,但它们都是int
类型的实例。
当您创建class
的实例时,您将创建所使用的空间以及该类实例上的行为,并且这些行为同样适用于每个实例。
类也可以做一些不是定义其实例的数据和行为的东西,而那些类是该类的静态成员。
由于这些概念基本上是分开的,因此它们并不真正相互干扰。实际上,你可以让类中的一个静态成员引用类的实例,而这正是单例模式的例子。
那么实际发生了什么,从一开始就是使用new GlobalClass
创建类的实例,然后将指针保持在某个位置。碰巧指针被保存为同一类的静态成员,该类定义了刚刚创建的实例的类型。
然后GlobalClass
提供了使用该实例的机制。当你调用GlobalClass::instance()
时,它会读取一个允许的静态类变量。该变量包含一个指针,当取消引用时(通过->
)会导致我们之前创建的一个对象,并且该对象现在被允许访问实例变量,因为它是GlobalClass的一个实例。
答案 2 :(得分:3)
instance
,顾名思义,返回指向实例的指针。它还使用静态实例指针字段s_instance
。这是静态的这一事实意味着每个类只有一个s_instance
字段。一旦获得该实例指针(来自instance
),就可以像使用任何其他实例指针一样使用它。通过静态方法获得的事实以及该方法使用静态字段的事实是无关紧要的。
静态方法本身是有效的;它不会隐式或明确地使用this
。
答案 3 :(得分:1)
技术问题已经发布在其他答案中,我将添加一个试图帮助解决混乱的例子。想象一下,你创建了一个人类来代表一个人类,它可以拥有像眼睛的颜色,名称等的属性......以及定义步行,跳跃等动作的方法......这些属性和方法是特别的人类的每个实例:一个特定的人可能有蓝眼睛,你可以让她说话。
在不同的级别中,可能存在不属于实例的属性或动作,而是整个人类类别,例如谁是最高或最年长的人类。那些被宣布为 static 属于整个人类,而不是属于每个人。
现在,一旦你从班级中获得一个人,说最高的,那个人就是一个人,因此你可以申请任何你想要的财产,或者你可以要求任何你需要的行动:Human::get_tallest().get_something_from_cupboard()
将请求集合中最高的(get_tallest()
)人员(集体诉讼),然后请求特定个人为您执行操作(get_something_from_cupboard()
),这是由特定实例执行的操作< / em>的