📄 staticmember.html
字号:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<link rel="stylesheet" href="css/stdlayout.css" type="text/css">
<link rel="stylesheet" href="css/print.css" type="text/css">
<meta content="text/html; charset=gb2312" http-equiv="content-type">
<title>static 成员</title>
</head>
<body>
<h3><a href="http://caterpillar.onlyfun.net/GossipCN/index.html">From
Gossip@caterpillar</a></h3>
<h1><a href="CppGossip.html">C++
Gossip: static 成员</a></h1>
对于每一个基于相同类别所产生的物件而言,它们会拥有各自的资料成员,然而在某些时候,您会想要这些物件拥有相同的资料成员,举个例子来说,在Ball类
别中,您打算使用到圆周率PI这个资料,因为对于任一个Ball的实例而言,圆周率都是相同的,您不需要让不同的Ball实例拥有各自的圆周率资料成员。<br>
<br>
您可以将PI资料成员宣告为"static",被宣告为"static"的资料成员,又称“静态资料成员”,静态成员是属于类别所拥有,而不是个别的物
件,您可以将静态成员视为每个物件实例所共享的资料成员。要宣告静态资料成员,只要在宣告资料成员时加上"static"关键字就可以了,例如:<br>
<ul>
<li>Ball.h</li>
</ul>
<pre>#include <string><br>using namespace std;<br><br>class Ball { <br>public: <br> // 宣告静态成员<br> static double PI;<br> // const 静态成员可以在类别定义中初始化<br> // static const double PI = 3.14159;<br><br> Ball(); <br> Ball(double, const char*); <br> Ball(double, string&); <br> <br> double radius() {<br> return _radius;<br> }<br> <br> string& name() {<br> return _name; <br> }<br> <br> void radius(double radius) {<br> _radius = radius;<br> } <br> <br> void name(const char *name) {<br> _name = name;<br> }<br> <br> void name(string& name) {<br> _name = name;<br> }<br> <br> double volumn() {<br> return (4 / 3 * PI * _radius * _radius * _radius); <br> }<br> <br>private:<br> double _radius; // 半径 <br> string _name; // 名称 <br>};</pre>
<br>
<ul>
<li>Ball.cpp</li>
</ul>
<pre>#include <string><br>#include "Ball.h"<br>using namespace std;<br><br>// 非const静态成员要在类别定义外初始化<br>double Ball::PI = 3.14159;<br><br>// 预设建构函式<br>Ball::Ball() {<br> _radius = 0.0; <br> _name = "noname ball"; <br>}<br><br>Ball::Ball(double radius, const char *name) { <br> _radius = radius; <br> _name = name;<br>}<br><br>Ball::Ball(double radius, string &name) { <br> _radius = radius; <br> _name = name;<br>}</pre>
<p class="MsoNormal" style="text-align: justify; text-indent: 24pt; line-height: 125%;"><span style="font-family: 新宋体;"></span></p>
<p class="MsoNormal" style="text-align: justify; text-indent: 24pt; line-height: 125%;"><span style="font-family: 新宋体;">非const的static成员要在类别定义区块之外初始化,静态成员属于类别所拥有,可以在
不使用名称参考下,直接使用类别名称加上</span><span style="font-weight: bold;" lang="EN-US"><span style="font-family: 新宋体;">::</span></span><span style="font-family: 新宋体;">运算子来存取静态资料成员,不过静态资料成员同样遵守</span><span lang="EN-US">"public"</span><span style="font-family: 新宋体;">、</span><span lang="EN-US">"protected"</span><span style="font-family: 新宋体;">与</span><span lang="EN-US">"private"</span><span style="font-family: 新宋体;">的存取限制,所以若
您要直接存取静态资料成员,必须注意它的权限,例如必须设定为</span><span lang="EN-US">"public"</span><span style="font-family: 新宋体;">成员的话就可以如下存取:</span></p>
<ul>
<li><span style="font-family: 新宋体;">main.cpp</span></li>
</ul>
<pre>#include <iostream><br>#include "Ball.h"<br>using namespace std;<br><br>int main() {<br> cout << Ball::PI <br> << endl;<br><br> return 0;<br>}</pre>
<br>
<span class="postbody">
执行结果:</span><br>
<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
<tbody>
<tr>
<td style="background-color: rgb(0, 0, 0);"><small><span style="color: rgb(255, 255, 255);">3.14159</span></small><span style="color: rgb(255, 255, 255);"><br>
</span></td>
</tr>
</tbody>
</table>
<br>
虽然您也可以在宣告物件之后,透过物件名称加上'.'运算子来存取静态资料成员,但是这个方式并不被鼓励,通常建议使用类别名称加上'.'运算子来存取,
一方面也可以避免与非静态资料成员混淆,例如下面的方式是不被鼓励的:<br>
<div style="margin-left: 40px;"><span style="font-weight: bold; font-family: Courier New,Courier,monospace;">Ball ball;</span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">cout <<
ball.PI << endl;</span><br>
</div>
<br>
与静态资料成员类似的,您也可以宣告函式成员为"static"方法,又称“静态函式”,被宣告为静态的函式通常是作为工具函式,例如在Ball类别上增
加一个角度转径度的函式toRadian():<br>
<ul>
<li><span style="font-family: 新宋体;">Ball.h</span></li>
</ul>
<pre>#include <string><br>using namespace std;<br><br>class Ball { <br>public: <br> // 宣告静态资料成员 <br> static double PI;<br> <br> Ball(); <br> Ball(double, const char*); <br> Ball(double, string&); <br> <br> // 宣告静态函式 <br> static double toRadian(double);<br> <br> double radius() {<br> return _radius;<br> }<br> <br> string& name() {<br> return _name; <br> }<br> <br> void radius(double radius) {<br> _radius = radius;<br> } <br> <br> void name(const char *name) {<br> _name = name;<br> }<br> <br> void name(string& name) {<br> _name = name;<br> }<br> <br> double volumn() {<br> return (4 / 3 * PI * _radius * _radius * _radius); <br> }<br> <br>private:<br> double _radius; // 半径 <br> string _name; // 名称 <br>};</pre>
<br>
<ul>
<li><span style="font-family: 新宋体;">Ball.cpp</span></li>
</ul>
<pre>#include <string><br>#include "Ball.h"<br>using namespace std;<br><br>// 初始静态资料成员 <br>double Ball::PI = 3.14159;<br><br>// 实作静态函式 <br>double Ball::toRadian(double angle) {<br> return 3.14159 / 180 * angle;<br>}<br><br>// 预设建构函式<br>Ball::Ball() {<br> _radius = 0.0; <br> _name = "noname ball"; <br>}<br><br>Ball::Ball(double radius, const char *name) { <br> _radius = radius; <br> _name = name;<br>}<br><br>Ball::Ball(double radius, string &name) { <br> _radius = radius; <br> _name = name;<br>}</pre>
<br>
与静态资料成员一样的,您可以透过类别名称使用::运算子来存取"static"函式,当然要注意权限设定,例如设定为"public"的话可以如下存
取:<br>
<div style="margin-left: 40px;"><span style="font-weight: bold; font-family: Courier New,Courier,monospace;">cout <<
"角度90等于径度" </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<< Ball::toRadian(90) </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<< endl;</span><br>
</div>
<br>
由于静态成员是属于类别而不是物件,所以当您呼叫静态函式时,并不会传入物件的位址,所以静态函式中不会有this指标,由于没有this指标,所以在C
++的静态函式中不允许使用非静态成员,因为没有this来储存物件的位址,也就无法辨别要存取的是哪一个物件的成员,事实上,如果您在静态函式中使用非
静态资料成员,在编译时就会出现以下的错误讯息:<br>
<div style="margin-left: 40px;"><span style="font-weight: bold; font-family: Courier New,Courier,monospace; color: rgb(255, 0, 0);">invalid use of member
`Ball::_radius' in static member function </span><br>
</div>
<br>
或者是在静态函式中呼叫非静态函式,在编译时就会出现以下的错误讯息:<br>
<div style="margin-left: 40px; color: rgb(255, 0, 0);"><span style="font-weight: bold; font-family: Courier New,Courier,monospace;">cannot call member
function `std::string& Ball::name()' without object </span><br>
</div>
<br>
<br>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -