c++静态成员的作用,c++类的静态成员变量
在C中,静态成员属于整个类而不是一个对象,只存储一份静态成员变量供所有对象共享。因此它可以在所有对象之间共享。使用静态成员变量在多个对象之间共享数据不会违背隐藏的原则,这样既保证了安全性又节省了内存。
静态成员的定义或声明需要一个关键静态。静态成员可以用双冒号,即类名:静态成员名。
C中类的静态成员变量和函数容易出错。本文首先通过几个例子总结了静态成员变量和函数的使用规则,然后举例加深印象。希望看完这篇文章能让读者对类的静态成员变量和成员函数有更深入的了解。
在第一个例子中,静态成员函数和非静态成员函数由类名调用。
分类点
{
公共:
void初始化()
{
}
静态void输出()
{
}
};
void main()
{
point:init();
点:输出();
}
错误:错误c 2352:“point:init”:非静态成员函数的非法调用
结论:类的非静态成员函数不能被类名调用。
在第二个示例中,静态成员函数和非静态成员函数通过类的对象调用。
将上面示例的main()更改为:
void main()
{
点pt;
pt . init();
pt . output();
}
编译通过。
结论:静态成员函数和非静态成员函数都可以用于类对象。
第三个示例在类的静态成员函数中使用了类的非静态成员。
#包含stdio.h
分类点
{
公共:
void初始化()
{
}
静态void输出()
{
printf(%d\n ,m _ x);
}
私人:
int m _ x;
};
void main()
{
点pt;
pt . output();
}
错误:错误c2597:静态成员函数中对数据成员“point: m _ x”的非法引用
因为静态成员函数是属于整个类的,在类实例化对象之前已经分配了空间,而类实例化对象之后类的非静态成员又要有内存空间,所以这个调用就出错了,就像提前使用了一个变量而没有声明它一样。
结论:不能在静态成员函数中引用非静态成员。
第四个例子是在类的非静态成员函数中使用类的静态成员。
分类点
{
公共:
void初始化()
{
output();
}
静态void输出()
{
}
};
void main()
{
点pt;
pt . output();
}
编译通过。
结论:类的非静态成员函数可以用静态成员函数调用,反之亦然。
第五个示例使用类的静态成员变量。
#包含stdio.h
分类点
{
公共:
点()
{
m _ nPointCount
}
~点()
{
m _ nPointCount-;
}
静态void输出()
{
printf(%d\n ,m _ nPointCount);
}
私人:
static int m _ nPointCount
};
void main()
{
点pt;
pt . output();
}
按Ctrl F7编译无错,按F7生成EXE程序并报告链接错误。
错误LNK2001:未解析的外部符号 private:static int Point:m _ nPointCount (?m_nPointCount@Point@@0HA)
这是因为类的静态成员变量必须在使用前初始化。
在main()函数前添加int Point:m _ nPointCount=0;
重新编译链接没有错误,运行的程序会输出1。
结论:类的静态成员变量必须在使用前初始化。
结合以上五个例子,总结了类的静态成员变量和成员函数:
一个。不能在静态成员函数中调用非静态成员。
两个。静态成员可以在非静态成员函数中调用。因为静态成员属于类本身,并且在类的对象产生之前就存在,所以静态成员可以在非静态成员函数中调用。
三个。静态成员变量在使用前必须初始化(如int my class:m _ n number=0;),否则会得到链接器错误。
再举一个使用类的静态成员变量和函数的例子来加深理解。这个例子建立了一个学生类,每个学生类的对象将形成一个双向链表。一个静态成员变量记录这个双向链表的头,一个静态成员函数输出这个双向链表。
#包含stdio.h
#包含字符串. h
const int MAX _ NAME _ SIZE=30
班级学生
{
公共:
学生(char * pszName);
~ Student();
公共:
静态void PrintfAllStudents();
私人:
char m _ NAME[MAX _ NAME _ SIZE];
学生*下一个;
学生*上一个
静态学生* m _ head
};
学生:学生(char *pszName)
{
strcpy(this- m_name,PSZ名);
//建立双向链表,新数据从链表头部插入。
this-next=m _ head;
this-prev=NULL;
如果(m_head!=空)
m _ head-prev=this;
m _ head=这个
}
学生:~学生()//析构过程就是节点的脱离过程
{
if (this==m_head) //该节点就是头节点。
{
m _ head=this-next;
}
其他
{
this-prev-next=this-next;
this-next-prev=this-prev;
}
}
void Student:PrintfAllStudents()
{
对于(学生* p=m _ headp!=NULLp=p-下一个)
printf(%s\n ,p-m _ name);
}
学生*学生* m _ head=NULL
void main()
{
学生学生甲(‘AAA’);
学生学生b(“BBB”);
学生学生c(“CCC”);
学生学生d(‘DDD’);
学生学生(‘更多窗口’);
student:PrintfAllStudents();
}
程序将输出:
当然在本例还可以增加个静态成员变量来表示链表中学生个数,如果读者有兴趣,就将这个作为小练习吧。
来自:http://www。cn博客。com/more windows/archive/2011/08/26/2154198。超文本标记语言
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。