C++类的常量数据成员,静态数据成员,常量静态数据成员,枚举类型

C++类的常量数据成员,静态数据成员,常量静态数据成员

const成员

const成员可以提供类内初始值,也可以在构造函数初始化列表中进行初始化。

#include <iostream>
using namespace std;

class A {
public:
    A(int temp) :j(temp){}
    A(int a, int b) : i(a), j(b) {}
    void print()
    {
        cout << "i: " << i << " " << "j: " << j << endl;
    }

private:
    const int i = 3;
    const int j;
};

int main()
{
    A a(4);
    a.print();
    A a1(5, 6);
    a1.print();
    return 0; 
}
/*
i: 3 j: 4
i: 5 j: 6
*/

const成员为什么不能在构造函数体中进行赋值呢?

构造函数创建对象时,对象在执行构造函数体执行前被创建(即分配存储空间)。因此,调用构造函数将为对象的成员变量分配内存,然后程序进入构造函数体内,使用常规的赋值方式对成员变量进行赋值。因此,对于const数据成员,必须在执行到构造函数体之前,即创建对象,进行初始化

static成员

初始化在类外,且不能加static修饰,且不能在类内提供初始值

#include <iostream>
using namespace std;

class A {
public:
    static int i;
    void print()
    {
        cout << i << endl;
    }
};
int A::i = 10;
int main()
{
    A a;
    a.print();   //输出10
    return 0; 
}

静态整型常量数据成员

#include <iostream>
using namespace std;

class A{
public:
    void print1()
    {
        cout << "i: " << i << " " << "j: " << j << endl;
    }
private:
    static const int i = 30;  
    static const int j;
}
const int A::j = 20;   //静态常量数据成员,在类外定义时,要加上const关键字
//const int A::i = 5;   //error,因为已经在类内定义过了,这样的话就是重复定义
int main()
{
	A a;
    a.print1();
    return 0;
}
  • 只有静态整型常量才可以在类内提供初始值。如果是static const double/float则不可以在类内提供初始值。static const int/short可以在类内提供初始值。
  • 如果静态整型常量在类内没有提供初始值,在类外初始化时,要加上const关键字。
  • 如果静态整型常量已经在类内提供初始值了,在类外不可以再次初始化,因为这样就重复定义了,可以只在类外声明

C++枚举类型

枚举类型定义格式为

enum <类型名> {<枚举常量表>};

应用举例

enum color_set1 {RED, BLUE, WHITE, BLACK};	//定义枚举类型color_set1
enum week {Sun, Mon, Tue, Wed, Thu, Fri, Sat};	//定义枚举类型week

枚举变量代表该枚举类型的变量可能取的值,编译系统为每个枚举常量指定一个整数值,默认状态下,这个整数就是所列举元素的序号,序号从0开始,可以在定义枚举类型时为部分或全部枚举常量指定整数值,在指定值之前的枚举常量仍按默认方式取值,而指定值之后的枚举常量按依次加1的原则取值,各枚举常量的值可以重复

enum fruit_set {apple, orange, banana=1, peach, grape}
//枚举常量apple=0,orange=1, banana=1,peach=2,grape=3

enum week {Sun=7, Mon=1, Tue, Wed, Thu, Fri, Sat};
//枚举常量Sun,Mon,Tue,Wed,Thu,Fri,Sat的值分别为7、1、2、3、4、5、6

枚举常量只能以标识符形式表示,而不能是整形,字符型等文字常量,以下定义非法:

enum letter_set {'a','d','F','s','T'}; //枚举常量不能是字符常量
enum year_set{2000,2001,2002,2003,2004,2005}; //枚举常量不能是整型常量

枚举变量的值只能取枚举常量表中所列的值,就是整型数的一个子集。

枚举变量占用内存的大小与整型数相同。

枚举变量只能参与赋值和关系运算以及输出操作,参与运算时用其本身的整数值。

enum color_set1 {RED, BLUE, WHITE, BLACK} color1, color2;
enum color_set2 { GREEN, RED, YELLOW, WHITE} color3, color4;

则允许的赋值操作如下:

color3=RED;           //将枚举常量值赋给枚举变量
color4=color3;        //相同类型的枚举变量赋值,color4的值为RED
int  i=color3;        //将枚举变量赋给整型变量,i的值为1
int  j=GREEN;         //将枚举常量赋给整型变量,j的值为0

允许的关系运算符有 = = , < , > , < = , > = , ! = ==,<,>,<=,>=, != ==,<,>,<=,>=,!=,例如:

//比较同类型枚举变量color3,color4是否相等
if (color3==color4) cout<<"相等";
//输出的是变量color3与WHITE的比较结果,结果为1
cout<< color3<WHITE;

枚举变量可以直接输出,输出的是变量的整数值。

cout << color3;		//输出的是color3的整数值,即RED的整数值1

重要提示

  • 枚举变量可以直接输出,但不能直接输入;
  • 不能直接将常量赋给枚举变量;
  • 不同类型的枚举变量之间不能相互赋值;

C++中作用域受限的枚举类型

一个典型的枚举类型定义如下:

enum Color {RED, BLUE};

这种枚举类型有如下的问题:

  • 作用域不受限,枚举变量的作用域不受限,会暴露给邻近的代码作用域(如果在最外层则为全局作用域),容易引起命名冲突,例如如下代码是无法编译通过的。

    • enum Color {RED, BLUE};
      enum Feeling {EXCITED, BLUE};
      
  • 会隐式转换为int,这是C中默认行为,但是和“有类型的常量”的初衷是不符合的,在上面的例子中EXCITED == RED会返回真。

经典做法

  • 使用命名空间

    • namespace Color {enum Type {RED, YELLOW, BLUE}; };
      
    • 这样就可以使用Color::type c = Color::RED定义新的枚举变量,如果使用using namespace Color后,前缀还可以省去,使得代码简化。

  • 使用一个类或结构体来限定其作用域,例如:

    • struct Color {enum Type {RED, YELLOW, BLUE}; };
      

C++11的枚举类

枚举类使用如下语法定义:

enum class Color { RED, BLACK };

定义新变量也得到了简化:

Color c = Color::RED;

类限制了其作用域,避免了命名冲突,同时也避免了隐式类型转换,也就是说,枚举类即是作用域受限的,又是强类型的枚举,C++11允许枚举类指定存储类型;

enum class Color:char {RED, BLUE};
  • 6
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值