电子说
>>> 背景
如果同时写两种类型语言的代码,难免有的时候会产生一点混淆,这也正是思维碰撞的时候。今天来讲一点Python类成员和C++类成员的构造区别。在C++里面,就要求把类成员显式地声明出来,这样才能够在构造函数里面对成员进行初始化,就如下所示。
class A
{
public:
int n_;
A(int n) : n_(n){}
};
如果使用python定义类的话,类成员的定义和初始化都放在了构造函数里面,少了那么一点仪式感,就如下面所示。
class Dog:
def __init__(self, m):
self.m_ = m
这个时候如果硬是要为python类先声明一个成员,从语法上也是可以的,如下所示。
class Dog:
n_ = 0
def __init__(self, n):
self.n_ = n
这就引出了今天的问题,在python中像 n_ = **0 **这样的语句,到底是什么含义呢?
>>> 解释
其实在上述代码中,为classDog创造了一个类静态成员,该静态成员为类所有的数据。而 self .m_ = m 才是为类的实例所有的数据。通过类静态成员,可以管理一些实例无关的数据,比如某个数学类中的圆周率、已经创建的实例的个数等等。
如下面就通过 count** *** 这个类静态成员,统计了实例化的次数;注意这里使用了 Dog.count*** ** 来访问类静态成员,而不是 self.count**_**。
class Dog:
count_ = 0
def __init__(self, n):
self.n_ = n
Dog.count_ += 1
if __name__ == '__main__':
for i in range(3):
g = Dog(2 * i)
print(Dog.count_, " n: ", g.n_)
>>
1 n: 0
2 n: 2
3 n: 4
相比而言,C++创建类静态成员的方法如下所示。使用关键字 static 来声明一个静态成员。对于非const类型的类静态成员,C++还要求在类外部进行初始化,如int Dog::count = 0 ; 。
注意下面这种统计构造次数的方法仅仅是统计了普通构造,并没有统计默认构造、拷贝构造或者赋值构造。通过析构函数可以看到,随着对象的过期,对象的个数也逐渐减少到归0了。
class Dog
{
public:
static int count;
int n_;
Dog(int n): n_(n) { count++; }
~Dog() { count--; }
};
int Dog::count = 0;
int main()
{
{
Dog g1(0);
cout < < Dog::count < < " n: " < < g1.n_ < < endl;
Dog g2(2);
cout < < Dog::count < < " n: " < < g2.n_ < < endl;
Dog g3(4);
cout < < Dog::count < < " n: " < < g3.n_ < < endl;
}
cout < < Dog::count < < endl;
}
>>
1 n: 0
2 n: 2
3 n: 4
0
全部0条评论
快来发表一下你的评论吧 !