IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 现代C++新特性 非静态数据成员默认初始化 -> 正文阅读

[C++知识库]现代C++新特性 非静态数据成员默认初始化

?????文字版PDF文档链接:现代C++新特性(文字版)-C++文档类资源-CSDN下载?

1.使用默认初始化

在C++11以前,对非静态数据成员初始化需要用到初始化列表,当类的数据成员和构造函数较多时,编写构造函数会是一个令人头痛的问题:

class X {
public:
    X() : a_(0), b_(0.), c_("hello world") {}
    X(int a) : a_(a), b_(0.), c_("hello world") {}
    X(double b) : a_(0), b_(b), c_("hello world") {}
    X(const string& c) : a_(0), b_(0.), c_(c) {}
private:
    int a_;
    double b_;
    string c_;
};

在上面的代码中,类X有4个构造函数,为了在构造的时候初始化非静态数据成员,它们的初始化列表有一些冗余代码,而造成的后果是维护困难且容易出错。为了解决这种问题,C++11标准提出了新的初始化方法,即在声明非静态数据成员的同时直接对其使用=或者{}(见下期的列表初始化)初始化。在此之前只有类型为整型或者枚举类型的常量静态数据成员才有这种声明默认初始化的待遇:

class X {
public:   X() {}
      X(int a) : a_(a) {}
      X(double b) : b_(b) {}
      X(const string& c) : c_(c) {}
private:
    int a_ = 0;   
    double b_{ 0. };
    string c_{ "hello world" };
};

以上代码使用了非静态数据成员默认初始化的方法,可以看到这种初始化的方式更加清晰合理,每个构造函数只需要专注于特殊成员的初始化,而其他的数据成员则默认使用声明时初始化的值。比如X(const string c)这个构造函数,它只需要关心数据成员 c_的初始化而不必初始化a_和b_。在初始化的优先级上有这样的规则,初始化列表对数据成员的初始化总是优先于声明时默认初始化。

最后来看一看非静态数据成员在声明时默认初始化需要注意的两个问题。

1.不要使用括号()对非静态数据成员进行初始化,因为这样会造成解析问题,所以会编译错误。

2.不要用auto来声明和初始化非静态数据成员,虽然这一点看起来合理,但是C++并不允许这么做。

struct X {
    int a(5);     // 编译错误,不能使用()进行默认初始化 
    auto b = 8;   // 编译错误,不能使用auto声明和初始化非静态数据成员 
};

2.位域的默认初始化

在C++11标准提出非静态数据成员默认初始化方法之后,C++20标准又对该特性做了进一步扩充。在C++20中我们可以对数据成员的位域进行默认初始化了,例如:

struct  S1 {
    int y : 8 = 11;  
    int z : 4 {7};
};

在上面的代码中,int数据的低8位被初始化为11,紧跟它的高4 位被初始化为7。

位域的默认初始化语法很简单,但是也有一个需要注意的地方。当表示位域的常量表达式是一个条件表达式时我们就需要警惕了,例如:

int a; 
struct S2 {
    int y : true ? 8 : a = 42;  
    int z : 1 || new int{ 0 };
};

请注意,这段代码中并不存在默认初始化,因为最大化识别标识符的解析规则让=42和{0}不可能存在于解析的顶层。于是以上代码会被认为是:

int a; 
struct S2 {
    int y : (true ? 8 : a = 42);   
    int z : (1 || new int{ 0 });
};

所以我们可以通过使用括号明确代码被解析的优先级来解决这个问题:

int a; 
struct S2 {
    int y : (true ? 8 : a) = 42;   
    int z : (1 || new int) { 0 };
};

通过以上方法就可以对S2::y和S2::z进行默认初始化了。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-01 23:08:08  更:2022-04-01 23:10:24 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 2:58:37-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码