栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++(11)——静态成员

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++(11)——静态成员

回顾:我们都知道C中的静态在修饰局部变量或函数和全局变量时是不太一样的。

局部变量可见性在其所在函数内部,并将其存储到.data区,在函数运行时只初始化一次,其生存期也会被延长,因此可以以引用方式返回。如果将函数或全局变量定义为静态,其生存期不会改变,仍然分别存放在代码区和.data区,但其只在定义它的文件中可见,同一个工程的其他文件不可见。 静态数据成员

在C++中静态数据成员有如下特点:

    在构造函数和拷贝构造函数中不能对静态数据成员进行列表方式构建,也就是不能在参数列表中对其进行初始化(在这两个函数体内部对其进行操作不能称之为初始化)必须在类外初始化,初始化方式为:类型名 类名::变量名 = 0;重要的一点:在类中的静态数据成员是所有类共享的数据成员,比如下面的代码:
class Object
{
public://这里主要是为了方便访问
	int value;
	static int num;
public:
	Object(int x = 0) :value(x)
	{
		num += 1;
	}
	Object(const Object& obj) :value(obj.value)
	{
		num += 1;
	}
	~Object()
	{
		num -= 1;
	}
};
int Object::num = 0;
int main()
{
	Object a(10);
	Object b(20);
	cout << &a.value << "  " << &a.num << endl;
	cout << &b.value << "  " << &b.num << endl;
}

运行结果如下:

我们可以看到两个对象的num数据成员地址相同,因此类中的静态数据成员是所有类共享的数据成员。
因此作为公有的静态数据成员,我们既可以用对象访问它,比如:a.num +-= 10;也可以用类型名访问它,Object::num = 100;。

但是大多数情况下数据成员我们都会设计为私有,此时在类外的语句难道不会报错吗?
不会,因为编译器会会认为那只是一个初始化语句,并不是一条执行语句,在进入主函数之前编译链接就已经完成了这部分工作,因此下面的代码依旧正确。

class Object
{
private:
	int value;
	static int num;
public:
	Object(int x = 0) :value(x)
	{
		num += 1;
	}
	Object(const Object& obj) :value(obj.value)
	{
		num += 1;
	}
	~Object()
	{
		num -= 1;
	}
};
int Object::num = 0;

解决下一个问题:在该类的常方法中,能否对num进行修改?

void Print() const
{
	num += 10;//ok
	cout<<"value:"< 

答案是可以的,因为num作为一个静态数据成员,他不属于任何类,因此也就没有this指针,在常方法内部的编译过程中,不会添加this指针,不会对其产生任何约束,因此也就可以对其进行修改。

静态成员函数

看下面的代码,这个静态成员函数是否可以完成其中的操作?

class Object
{
private:
	int value;
	static int num;
public:
	Object(int x = 0) :value(x)
	{
		num += 1;
	}
	Object(const Object& obj) :value(obj.value)
	{
		num += 1;
	}
	~Object()
	{
		num -= 1;
	}
	static int show()
	{
		num += 10;
		cout<<"value:"< 

答案是不可以的。
其实普通的成员函数既可以访问普通成员(非静态成员),也可以访问静态成员。
但是静态成员函数的一大特点就是:编译器在编译过程中只会标识它是哪一个类的静态成员函数,并不会添加this指针,没有this指针,所以只能够访问静态成员,不能够访问非静态成员。

同理,静态函数可以通过类名直接访问,也可以通过变量名直接访问。

因此上述的静态成员函数也不可声明为常方法,因为在编译过程中就没有this指针。

问题:静态函数有没有办法访问到非静态成员呢?

答案是可以的,因为静态函数可以设计成带参类型,参数是该对象的引用,在函数体内访问或者操作非静态成员,此时既可以通过对象名对非静态成员进行访问,也可以通过类名加上作用域解析符来访问类中的非静态成员,看下面的代码:

class Object
{
private:
    int value;
    static int num;
public:
    Object(int x = 0):value(x){}
    static void Show(Object & obj)
    {
        obj.value += 10;
        cout< 

运行结果如下:成功地通过静态成员函数访问到了非静态数据成员

辨析下列程序哪一个可以编译通过?

A

class Object
{
public:
	int value;
	Object obj;
};

这个无法编译通过,因为会形成递归创建过程,无穷递归下去

B

class Object
{
public:
	int value;
	Object & obj ;
};

这个也无法编译通过,因为在构建原对象时,obj必须引用一个已经存在的对象,无法做到
C

class Object
{
public:
	int value;
	Object *pobj;
};

这个可以编译通过,因为这个指针即便没有指向任何对象,后期也可以认为修改
D

class Object
{
public:
	int value;
	static Object obj;
};

这个也可以编译通过,因为静态成员不属于对象,任何对象都不会有内部对象

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/738046.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号