C++ 类对象其它成员及其初始化

类对象其它成员及其初始化

类的 const 成员

const 数据成员

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

cpp 复制代码
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 数据成员可以设置类内初始值。

cpp 复制代码
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 成员函数只能引用本类中的数据成员,而不能修改它们。

cpp 复制代码
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 成员函数如果以引用的形式返回*this,那么它的返回类型将是常量引用。

cpp 复制代码
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 的。

cpp 复制代码
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 对象中数据成员的值。

cpp 复制代码
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 函数的参数或返回类型。

一个字面值常量类

cpp 复制代码
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对象只能调用构造函数创建。

cpp 复制代码
    constexpr Birthday b{ 2012,3,12 };
    b.Print();

静态成员

静态数据成员

静态数据成员不能使用构造函数进行初始化,只能在类体外初始化。

在类外初始化静态数据成员时,不能重复 static 关键字。

cpp 复制代码
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 静态数据成员可以指定类内初始值。

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

静态数据成员在程序运行开始时被分配空间,程序结束时释放空间。

该类的所有对象共享一个或多个静态数据成员。

静态成员函数

静态成员函数不与任何对象绑定,没有 this 指针,不能访问本类中非静态成员。

静态成员函数不能声明成 const 的。

cpp 复制代码
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;
}

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

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

cpp 复制代码
int main()
{
    cout << Box::GetNumber() << endl;
    //没有对象生成,number = 0;
    Box B1;
	Box B2{ 1,1,1};
    cout << B2.GetNumber() << endl;
    //生成了两个对象,number = 2;
	return 0;
}

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

友元

友元(friend )机制允许一个类授权其他的函数或类访问它的私有成员。

friend 关键字只能出现在声明中。

可以在类声明中,声明一个全局函数为友元函数。

可以在类声明中,声明其他类为友元类。

可以在类声明中,声明其他类中的函数为友元函数。

一般来说,最好在类定义开始或结束前的位置集中声明友元。

相关推荐
奋斗的小花生4 小时前
c++ 多态性
开发语言·c++
闲晨4 小时前
C++ 继承:代码传承的魔法棒,开启奇幻编程之旅
java·c语言·开发语言·c++·经验分享
UestcXiye6 小时前
《TCP/IP网络编程》学习笔记 | Chapter 3:地址族与数据序列
c++·计算机网络·ip·tcp
霁月风7 小时前
设计模式——适配器模式
c++·适配器模式
jrrz08287 小时前
LeetCode 热题100(七)【链表】(1)
数据结构·c++·算法·leetcode·链表
咖啡里的茶i7 小时前
Vehicle友元Date多态Sedan和Truck
c++
海绵波波1078 小时前
Webserver(4.9)本地套接字的通信
c++
@小博的博客8 小时前
C++初阶学习第十弹——深入讲解vector的迭代器失效
数据结构·c++·学习
爱吃喵的鲤鱼9 小时前
linux进程的状态之环境变量
linux·运维·服务器·开发语言·c++
7年老菜鸡9 小时前
策略模式(C++)三分钟读懂
c++·qt·策略模式