题
很抱歉,如果这个问题对很多人来说似乎微不足道。
在C ++代码中,有如下内容:
class Foo
{
public:
static int bands;
...
...
private:
...
...
}//class definition ends
int Foo::bands; //Note: here its not initialized to any value!
-
为什么当'band'在类中被声明为静态时再次需要上述语句?
-
还可以在任何类中将静态变量声明为私有成员变量吗?
醇>
解决方案
C ++注意到声明和定义之间的区别。 bands
在类中声明,但未定义。
当您定义该类型的对象时,将定义非静态数据成员,但由于静态成员不是任何一个特定对象的一部分,因此它需要它自己的定义。
其他提示
a)这是必要的,因为这就是语言的设计方式。
b)静态变量由其默认构造函数初始化,或者对于内置类型初始化为零。
c)是的,他们可以(并且通常是)私人。
请参阅此问题。
它与obj文件,它们的使用方式以及如何通过链接过程最终发现全局范围变量的内存地址有关。对象文件包含相应cpp中定义的所有全局数据和函数的地址。它们以相对的方式布局一些内存,以告诉liker在该文件中可以找到这些全局变量/函数的位置。例如,
function doFoo can be found 0 bytes from beginning of this file
int foo::bands can be found 12 bytes from beginning of this file
etc
如果你以前做过C,那几乎更容易思考。在纯粹的C世界中,您可以采用更传统的模块化编程方式。您的模块将使用标头和cpp定义。标题将定义“公共”标题。变量如下所示,使用extern关键字,然后在cpp。
中实例化它foo.h中
extern int bands;
Foo.cpp中
#include "foo.h"
int bands;
foo.obj:
int bands can be found 0 bytes from the beginning of this file
“extern”关键字指出此名称有效且其地址将在链接时解析。包含“foo.h”的所有人并希望使用“乐队”全局变量现在可以使用它了。在链接时,链接器会发现foo.obj中存在band。如果你忘了放“int band”在foo.obj中,你会收到链接器错误,必须解决它。
在C ++中使用类声明中的static类似。你告诉用户存在这个名为“foo :: bands”的东西。它将在哪里生活将在链接时解决。接下来,链接器看到在foo.obj中,foo :: bands存在,并且可以解析对foo :: bands的所有引用。
我的理解是,如果您计划在创建类的实例之前使用它,则只需要声明Foo :: bands。基本上,当您在C ++类中声明静态时,该类的所有实例只存在该变量的一个副本。但是,在声明类的实例之前,通常无法访问Foo :: band。
例如:
#include <iostream>
using namespace std;
class X {
public:
int a;
void f(int b) {
cout << "The value of b is "<< b << endl;
}
};
int main() {
// declare pointer to data member
int X::*ptiptr = &X::a;
// declare a pointer to member function
void (X::* ptfptr) (int) = &X::f;
// create an object of class type X
X xobject;
// initialize data member
xobject.*ptiptr = 10;
cout << "The value of a is " << xobject.*ptiptr << endl;
// call member function
(xobject.*ptfptr) (20);
}