【C++】类的特殊成员变量+初始化列表
参考资料:
1.黄邦勇帅
2.http://blog.163.com/sunshine_linting/blog/static/448933232011810101848652/
3.http://www.cnblogs.com/zhoug2020/archive/2012/08/31/2665451.html
一、初始化列表
1.假如定义了类 www 则 www::www (int i, int j, int k):x (i), y(j), z(k){},定义了一个带 i,j,k 三个参数的构造函数
2.初始化列表的初始化顺序:初始化列表的初始化次序是按成员变量在类中的声明次序执行的,而不是按初始化列表列出的顺序初始化的。
例如在类 hyong 中依次声明 int a,b,c;那么 hyong():c(a),b(2),a(3){}语句执行顺序是先把 a 初始化为 3,再把 b 初始化为 2,最后把 a 的值赋给变量 c,这是正确的。
但是 hyong():c(1),b(2),a(c){}就会出错,因为这时执行顺序是先把变量 c 的值赋给变量 a,而不是先把整数 1 赋给变量 c,所以这时变量 c 还未被初始化,而变量 a 就会得到一个错误的值。
3.必须使用初始化列表的情况:const成员、引用成员赋值
二、特殊成员变量
1.静态成员变量
#include <iostream.h>
class Myclass
{
public:
Myclass(int a,int b,int c);
void GetSum(); private:
int a,b,c;
static int Sum;//声明静态数据成员 声明时加上static
};
int Myclass::Sum=;//定义并初始化静态数据成员 定义初始化的时候不加static Myclass::Myclass(int a,int b,int c)
{
this->a=a;
this->b=b;
this->c=c;
Sum+=a+b+c;
} void Myclass::GetSum()
{
cout < <"Sum=" < <Sum < <endl;
}
1. 静态数据成员存储在全局数据区。静态数据成员定义时要分配空间,所以不能在类声明中定义。
2. 静态数据成员和普通数据成员一样遵从public,protected,private访问规则
3. 因为静态数据成员在全局数据区分配内存,属于本类的所有对象共享,所以,它不属于特定的类对象,在没有产生类对象时其作用域就可见,即在没有产生类的实例时,我们就可以操作它
4. 类内是声明,类外是定义!
5. 静态成员函数
静态成员函数与静态数据成员一样,都是类的内部实现,属于类定义的一部分。普通的成员函数一般都隐含了一个this指针,this指针指向类的对象本身,因为普通成员函数总是具体的属于某个类的具体对象的。通常情况下,this是缺省的。如函数fn()实际上是this->fn()。
#include <iostream.h>
class Myclass
{
public:
Myclass(int a,int b,int c);
static void GetSum();/声明静态成员函数
private:
int a,b,c;
static int Sum;//声明静态数据成员
};
int Myclass::Sum=;//定义并初始化静态数据成员 Myclass::Myclass(int a,int b,int c)
{
this->a=a;
this->b=b;
this->c=c;
Sum+=a+b+c; //非静态成员函数可以访问静态数据成员
} void Myclass::GetSum() //静态成员函数的实现
{
// cout < <a < <endl; //错误代码,a是非静态数据成员 静态成员函数由于不是与任何的对象相联系,因此它不具有this指针。从这个意义上讲,它无法访问属于类对象的非静态数据成员,也无法访问非静态成员函数,它只能调用其余的静态成员函数。
cout < <"Sum=" < <Sum < <endl;
} void main()
{
Myclass M(,,);
M.GetSum();
Myclass N(,,);
N.GetSum();
Myclass::GetSum();
}
关于静态成员函数,可以总结为以下几点:
出现在类体外的函数定义不能指定关键字static;
静态成员之间可以相互访问,包括静态成员函数访问静态数据成员和访问静态成员函数;
非静态成员函数可以任意地访问静态成员函数和静态数据成员;
静态成员函数不能访问非静态成员函数和非静态数据成员;
由于没有this指针的额外开销,因此静态成员函数与类的全局函数相比速度上会有少许的增长;
静态成员函数不能是虚函数:因为虚函数是动态决定的,而static函数时静态的,矛盾。
同一个函数,不能有静态、非静态两个版本。
2.其他特殊成员变量及初始化
这些特殊的类型的成员变量包括:
a.引用
b.常量
c.静态
d.静态常量(整型)
e.静态常量(非整型)
常量和引用,必须通过参数列表进行初始化。
静态成员变量的初始化也颇有点特别,是在类外初始化且不能再带有static关键字,其本质见文末。
① 单纯的const变量和引用型变量:必须在初始化列表中初始化。而且在所有的构造函数中都要用初始化列表。
② 带static修饰的变量,不管是普通变量还是const型变量,都要在类外初始化,不在构造函数里。
③ static const int型变量,可以在类的声明里初始化。
参考下面的代码以及其中注释:
#include <iostream>
using namespace std; class BClass
{
public:
BClass() : i(), ci(), ri(i){} // 对于常量型成员变量和引用型成员变量,必须通过参数化列表的方式进行初始化
//普通成员变量也可以放在函数体里,但是本质其实已不是初始化,而是一种普通的运算操作-->赋值运算,效率也低
private:
int i; // 普通成员变量
const int ci; // 常量成员变量
int &ri; // 引用成员变量
static int si; // 静态成员变量
//static int si2 = 100; // error: 只有静态常量成员变量,才可以这样初始化
static const int csi; // 静态常量成员变量
static const int csi2 = ; // 静态常量成员变量的初始化(Integral type) (1)
static const double csd; // 静态常量成员变量(non-Integral type)
//static const double csd2 = 99.9; // error: 只有静态常量整型数据成员才可以在类中初始化
}; //注意下面三行:不能再带有static
int BClass::si = ; // 静态成员变量的初始化(Integral type)
const int BClass::csi = ; // 静态常量成员变量的初始化(Integral type)
const double BClass::csd = 99.9; // 静态常量成员变量的初始化(non-Integral type) // 在初始化(1)中的csi2时,根据著名大师Stanley B.Lippman的说法下面这行是必须的。
// 但在VC2003中如果有下面一行将会产生错误,而在VC2005中,下面这行则可有可无,这个和编译器有关。
const int BClass::csi2; int main()
{
BClass b;
return ;
}
静态成员属于类作用域,但不属于类对象,和普通的static变量一样,程序一运行就分配内存并初始化,生命周期和程序一致。
所以,在类的构造函数里初始化static变量显然是不合理的。
静态成员其实和全局变量地位是一样的,只不过编译器把它的使用限制在类作用域内(不是类对象,它不属于类对象成员),要在类的定义外(不是类作用域外)初始化。
【C++】类的特殊成员变量+初始化列表的更多相关文章
- c++ 类成员变量初始化总结
最近在学习c++,不同类型的c++成员变量在初始化的时候也有很有的区别,查了一些资料之后再此记录一下: #include<iostream> using namespace std; // ...
- const成员变量初始化总结
const可以用来声明常量也就是说他的值不能被修改: const成员必须在定义的时候同时初始化,不能进行赋值 如 const int a:a的值不能修改,不能给它赋值,如何才能让它一开始就拥有一个值? ...
- C++成员变量初始化顺序问题
由于面试题中,考官出了一道简单的程序输出结果值的题:如下, class A { private: int n1; int n2; public: A():n2(0),n1(n2+2){} void P ...
- Java类变量和成员变量初始化过程
一.类的初始化 对于类的初始化:类的初始化一般只初始化一次,类的初始化主要是初始化静态成员变量. 类的编译决定了类的初始化过程. 编译器生成的class文件主要对定义在源文件中的类进行了如下的更改: ...
- android 20 Intnet类重要的成员变量
Intnet类重要的成员变量: <intent-filter> <action android:name="android.intent.action.MAIN" ...
- Java构造方法、成员变量初始化以及静态成员变量初始化三者的先后顺序是什么样的?
[Java笔试真题]:构造方法.成员变量初始化以及静态成员变量初始化三者的先后顺序是什么样的? [解答]:当类第一次被加载的时候,静态变量会首先初始化,接着编译器会把实例变量初始化为默认值,然后执行构 ...
- 假如java类里的成员变量是自身的对象
假如java类里的成员变量是自身的对象,则新建该类对象时内存中怎么分配空间,我感觉似乎死循环了. 不过我想的肯定是错的,因为很多类的成员变量是自身对象,并且绝对无错,举个例子: Class A{ pr ...
- 测试 Java 类的非公有成员变量和方法
引言 对于软件开发人员来说,单元测试是一项必不可少的工作.它既可以验证程序的有效性,又可以在程序出现 BUG 的时候,帮助开发人员快速的定位问题所在.但是,在写单元测试的过程中,开发人员经常要访问类的 ...
- CB XE7 C11 64位编译器 成员变量初始化
看到了C++11,看到了XE7的64位,想实现下面方便的类成员初始化,失望. 一.64位用法 clang3,64位编译器,不支持中文变量名,编写代码提示没有32位快,风格简单不用写单独的赋值语句函数, ...
随机推荐
- HDU 4565 So Easy!(数学+矩阵快速幂)(2013 ACM-ICPC长沙赛区全国邀请赛)
Problem Description A sequence Sn is defined as:Where a, b, n, m are positive integers.┌x┐is the cei ...
- 数据结构7——DP优化
斜率优化/单调队列优化/四边形优化
- windbg*****************************TBD
achieve structure from a simple address Dt address know pending IRP in a module !thread xxxxxx到底能提供哪 ...
- typescript 贪吃蛇[学习过程中,模仿的一个例子]
代码实现ts: 1 'use strict' module Main { const FloorType = { space: "space", snack: "body ...
- CSS的基本使用
CSS的出现就是为了将HTML的内容与样式分离 CSS的书写方式 selector{ key:value } h1{ color: blue; } <!DOCTYPE html> < ...
- [bzoj1018] [SHOI2008]堵塞的交通
题目描述 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常奇特,整个国家的交通系统可以被看成是一个22行CC列的矩形网格,网格上的每个点代表一个城市,相邻的城市之间有一条道路,所 ...
- [洛谷P4949]最短距离
题目大意:给一棵基环树,两种操作: $1\;x\;y:$把第$x$条边长度改成$y$ $2\;x\;y:$查询$x$到$y$的最短距离 题解:发现最短距离只有两种可能,第一个是树上的距离,第二种是经过 ...
- [Leetcode] Populating next right pointer in each node ii 填充每个节点的右指针
Follow up for problem "Populating Next Right Pointers in Each Node". What if the given tre ...
- POJ3294 Life Forms 【后缀数组】
生命形式 时间限制: 5000MS 内存限制: 65536K 提交总数: 16660 接受: 4910 描述 你可能想知道为什么大多数外星人的生命形式与人类相似,不同的是表面特征,如身高,肤色 ...
- [ZJOI2005]午餐 (DP)
[ZJOI2005]午餐 题目描述 上午的训练结束了,THU ACM小组集体去吃午餐,他们一行N人来到了著名的十食堂.这里有两个打饭的窗口,每个窗口同一时刻只能给一个人打饭.由于每个人的口味(以及胃口 ...