一、问题引入
类中是否可以定义const成员?
-
下面的类定义是否合法?
-
如果合法,ci的值是什么,存储在哪里?
class Test { private: const int ci; public: int getCI() { return ci; } };
-
编程实验
#include <stdio.h>
class Test
{
private:
const int ci;
public:
Test()
{
ci = 10;
}
int getCI()
{
return ci;
}
};
int main()
{
Test t1;
printf("t1.getCI() = %d\n",t1.getCI());
return 0;
}
/*编译效果如下:
test.cpp:8:2: error: uninitialized const member in ‘const int’ [-fpermissive]
Test()
^
test.cpp:6:12: note: ‘const int Test::ci’ should be initialized
const int ci;
^
test.cpp:10:6: error: assignment of read-only member ‘Test::ci’
ci = 10;
*/
二、类成员的初始化
-
C++中提供了初始化列表对成员变量进行初始化
-
语法规则
ClassName::ClassName(): m1(v1),m2(v1,v2),m3(v3) { }
注意事项:
- 成员的初始化顺序与成员的声明顺序相同
- 成员的初始化顺序与初始化列表中的位置无关
- 初始化列表先于构造函数的函数体执行
#include <stdio.h>
class Value
{
private:
int mi;
public:
Value(int i)
{
printf("i = %d\n",i);
mi = i;
}
int getI()
{
return mi;
}
};
class Test
{
private:
Value m2;
Value m3;
Value m1;
public:
Test():m1(1),m2(2),m3(3)
{
printf("Test:Test()\n");
}
};
int main()
{
Test t1;
return 0;
}
/*
i = 2
i = 3
i = 1
Test:Test()
*/
三、类中的const成员
- 类中的const成员会被分配空间的
- 类中的const成员的本质是只读变量
- 类中的const成员只能在初始化列表中指定初始值
编译器无法直接得到const成员的初始值,因此无法进入符号表成为正真意义上的常量
编程实验
#include <stdio.h>
class Value
{
private:
int mi;
public:
Value(int i)
{
printf("i = %d\n",i);
mi = i;
}
int getI()
{
return mi;
}
};
class Test
{
private:
const int ci;
Value m2;
Value m3;
Value m1;
public:
Test():m1(1),m2(2),m3(3),ci(100)
{
printf("Test:Test()\n");
}
int getCI()
{
return ci;
}
int setCI(int v)
{
int* p = const_cast<int*>(&ci);
*p = v;
}
};
int main()
{
Test t1;
printf("t.ci = %d\n",t1.getCI());
t1.setCI(10);
printf("t.ci = %d\n",t1.getCI());
return 0;
}
/*
i = 2
i = 3
i = 1
Test:Test()
t.ci = 100
t.ci = 10
*/
总结:
初始化与赋值不同
- 初始化:对正在创建的对象进行初值设置
- 赋值:对已经存在的对象进行值设置
小结:
- 类中可以使用初始化列表对成员进行初始化
- 初始化列表先于构造函数体执行
- 类中可以定义const成员变量
- const成员变量必须在初始化列表中指定初值
- const成员变量为只读变量