C++ const 成员和静态成员

const 成员和静态成员

类的 const 成员

const 数据成员

只能同过构造函数初始值列表对 const 数据成员进行初始化。

class Box {
private:
    const int length;     //长度 
	const int width;      //宽度 
	const int height;     //高度
public:       
    Box();    
    Box(int H, int W, int L); 
};
Box::Box(int H, int W, int L) : height{ H }, width{ W }, length{ L } {}
Box::Box() : height{ 1 }, width{ 2 }, length{ 3 } {}

const 数据成员可以设置类内初始值。

class Box {
private:
    const int length = 3;     //长度 
	const int width = 4;      //宽度 
	const int height = 5;     //高度
public:
    Box() = default;          
    Box(int H, int W, int L); 
};
Box::Box(int H, int W, int L) : height{ H }, width{ W }, length{ L } {}

const 成员函数

在函数的参数列表后面添加 const 关键字,这样使用 const 的成员函数被称作常量成员函数(const member function)。
const 成员函数只能引用本类中的数据成员,而不能修改它们。

class Box {
private:
    const int length;     //长度 
	const int width;      //宽度 
	const int height;     //高度
public:     
    Box() = default;        
    Box(int H, int W, int L); 
    void Print(void) const;  //声明,打印长,宽,高
};
Box::Box(int H, int W, int L) : height{ H }, width{ W }, length{ L } {}
void Box::Print(void) const  //定义也用 const 修饰
{
    cout << length << ' ' << width << ' ' << height << endl;
}

const 和非 const 对象都可以调用 const 成员函数,而非 const 成员函数只能被非 const 对象调用。
一个 const 成员函数如果以引用的形式返回*this,那么它的返回类型将是常量引用。

class Box {
private:
    int length;     //长度 
	int width;      //宽度 
	int height;     //高度
public:
    Box() = default;           
    Box(int H, int W, int L); 
    const Box & Print(void) const; //返回常量引用
};
Box::Box(int H, int W, int L) : height{ H }, width{ W }, length{ L } {}
const Box & Box::Print(void) const //返回常量引用
{
    cout << length << ' ' << width << ' ' << height << endl;
    return *this;
}

构造函数不能声明为 const 的。

mutable 数据成员

如果希望通过 const 成员函数修改数据成员,可以将数据成员声明为 mutable 的。

class Box {
private:
    int length;     //长度 
	int width;      //宽度 
    mutable int height;     //高度,声明为 mutable
public:
    Box() = default;         
    Box(int H, int W, int L); 
    int Volume(int h) const; //修改盒子高度,并求体积
};
Box::Box(int H, int W, int L) : height{ H }, width{ W }, length{ L } {}
int Box::Volume(int h) const //修改盒子高度,并求体积
{
    height = h;  //盒子高度可修改
    return length * width * height;
}

const 对象

定义对象时可以加关键字 const,指定对象为 const 对象。
const 对象必须要有初值,对象中的所有数据成员都不能被修改。
const 对象只能调用它的 const 成员函数(除了析构和构造),const 成员函数是 const 对象的唯一对外接口。
const 成员函数可以访问 const 对象中的数据成员,但仍然不允许修改 const 对象中数据成员的值。

const Box B1;          //调用无参构造
const Box B2{1,2,3};   //调用有参构造
B1.Print();            //调用 const 成员函数
B1.Volume(10); //可以修改 mutable 数据成员

聚合类

聚合类(aggregate class)使得用户可以直接访问其成员,并且具有特殊的初始化语法形式。
当一个类满足如下条件时,我们说它是聚合的:

  • 所有成员都是 public 的。
  • 没有定义任何构造函数。
  • 没有类内初始值。
  • 没有基类,也没有虚函数。

字面值常量类

数据成员都是字面值类型的聚合类是字面值常量类。
如果一个类不是聚合类,但它符合下述要求,则它也是一个字面值常量类:

  • 数据成员都必须是字面值类型。
  • 类必须至少含有一个 constexpr 构造函数。
  • 如果一个数据成员含有类内初始值,则内置类型成员的初始值必须是一条常量表达式;或者如果成员属于某种类类型,则初始值必须使用成员自己的 constexpr 构造函数。
  • 类必须使用析构函数的默认定义。

constexpr 构造函数

尽管构造函数不能是 const 的,但是字面值常量类的构造函数可以是 constexpr 函数。
constexpr 构造函数必须初始化所有数据成员,初始值或者使用 constexpr 构造函数,或者是一条常量表达式。
constexpr 构造函数用于生成 constexpr 对象以及 constexpr 函数的参数或返回类型。

一个字面值常量类

class Birthday
{
private:
    unsigned int year = 0;   //年
    unsigned int month = 0;  //月
    unsigned int day =0;     //日
public:
    constexpr Birthday() = default;
    constexpr Birthday(unsigned int y, unsigned int m, unsigned int d); //constexpr 构造函数
    void Print(void) const;
};
constexpr Birthday::Birthday(unsigned int y, unsigned int m, unsigned int d) :
    year{ y }, month{ m }, day{ d } {}
void Birthday::Print(void) const
{
    cout << year << " 年 " << month << " 月 " << day<< " 日" << endl;
}

constexpr 对象

constexpr对象只能调用它的 constexpr 成员函数。
constexpr对象只能调用构造函数生成。

    constexpr Birthday b{ 2012,3,12 };
    b.Print();

静态成员

静态数据成员

是类的一部分但不是某个类对象一部分的变量称为 static 成员。
静态数据成员不能使用构造函数进行初始化,只能在类体外初始化。
在类外初始化静态数据成员时,不能重复 static 关键字。

class Box {
private:
    int length;     //长度 
	int width;      //宽度 
    int height;     //高度
    static int number; //统计盒子个数
public:     
    Box();    
    Box(int H, int W, int L);
};
int Box::number = 0;  //类外初始化静态数据成员

const 静态数据成员可以指定类内初始值。
但是,static 数据成员必须是整型或枚举类型的 const,或字面值类型的 constexpr,且初始化器必须是一个常量表达式(constant-expression)。

class Box {
private:
    int length;     //长度 
	int width;      //宽度 
    int height;     //高度
    const static int number = 0; //const 静态数据成员
public:       
    Box();    
    Box(int H, int W, int L);
};

静态数据成员在程序运行开始时被分配空间,程序结束时释放空间。
该类的所有对象共享一个或多个静态数据成员。

静态成员函数

类似地,需要访问类成员而不需要通过特定对象调用的函数称为 static 成员函数。
静态成员函数不与任何对象绑定,没有 this 指针,不能访问本类中非静态成员。
静态成员函数不能声明成 const 的。

class Box {
private:
    int length;     //长度 
	int width;      //宽度 
    int height;     //高度
    static int number; //统计盒子个数
public:    
    Box();    
    Box(int H, int W, int L);
    static int GetNumber(void); //静态成员函数
};
int Box::number = 0;
Box::Box(int H, int W, int L) : height{ H }, width{ W }, length{ L }
{
    number += 1; //每创建一个盒子number加一
}
Box::Box() : height{ 1 }, width{ 2 }, length{ 3 } 
{
    number += 1; //每创建一个盒子number加一
}
int Box::GetNumber(void)  //静态成员函数
{
    return number;
}

没有定义对象,静态成员也可以通过类名引用。

    cout << Box::GetNumber() << endl;
    //没有对象生成,number = 0;

虽然静态成员不属于类的某个对象,但是我们仍然可以使用类的对象、引用或者指针来访问静态成员。

int main()
{
    Box B1;
	Box B2{ 1,1,1};
    cout << B2.GetNumber() << endl;
    //生成了两个对象,number = 2;
	return 0;
}

在类外定义静态成员时,不能重复 static 关键字。

  • 8
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

往昔的恒纳兰那

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值