zoukankan      html  css  js  c++  java
  • 类6(聚合类/字面值常量类)

    聚合类:

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

    1.所有成员都是 public 的

    2.没有定义任何构造函数

    3.没有类内初始值

    4.没有基类,也没有 virtual 函数

    如:

     1 #include <iostream>
     2 using namespace std;
     3 
     4 struct data{
     5     int ival;
     6     string s;
     7 };
     8 
     9 int main(void){
    10     data val = {1, "hello"};//聚合类可以使用花括号括起来的成员初始值列表,并用它来初始化数据成员
    11     data gel = {1};
    12     cout << gel.ival << " " << gel.s << endl;//输出1 ,s被值初始化
    13     return 0;
    14 }

    注意:初始值的顺序必须与声明的顺序一致,否则会出现与预期不一致的结果。如果初始值少于成员数量,则靠后的成员被值初始化。初始值的数量不能少于成员数量。

    显示地初始化类的对象的成员存在三个明显的缺点:

    1.要求类的所以成员都是 public 的。            

    2.将正确初始化每个对象的每个成员的任务交给了类的用户。因为用户很容易忘掉某个初始值,或者提供一个不恰当的初始值,所以这样的初始化过程冗长且容易出错。

    3.添加或者删除一个成员之后,所有的初始化语句都需要更新。

    字面值常量类:

    和一般类不同,字面值常量类可能含有 constexpr 函数成员。这样的成员必须复合 constexpr 函数的所有要求,且是隐式 const 的。

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

    1.数据成员都必须是字面值类型

    2.类必须至少含有一个 constexpr 构造函数

    3.如果一个数据成员含有类内初始值,则内置类型成员的初始值必须是一条常量表达式;或者说如果成员属于某种类类型,则初始值必须使用成员自己的 constexpr 构造函数。

    4.类必须使用析构函数的默认定义,该成员负责销毁类的对象。

    constexpr 构造函数:

    尽管构造函数不能是 const 的,但是字面常量类的构造函数可以是 constexpr 函数。事实上,一个字面值常量类必须至少提供一个 constexpr 构造函数。

    constexpr 构造函数可以声明成 =default 的形式(或者删除函数的形式)。否则,constexpr 构造函数就必须既符合构造函数的要求(意味着不能包含返回语句),又符合constexpr 函数的要求(意味着它能拥有的唯一可执行语句就是返回语句)。综合这两点可知,constexpr 构造函数体一般来说应该是空的。我们通过前置关键字 constexpr 就可以声明一个constexpr 构造函数了:

     1 #include <iostream>
     2 using namespace std;
     3 
     4 class Debug{
     5 public:
     6     constexpr Debug(bool b = true) : hw(b), io(b), other(b) {}
     7     constexpr Debug(bool h, bool i, bool o) : hw(h), io(i), other(o) {}
     8     constexpr bool any() {return hw || io || other;}
     9     void set_io(bool b) {io = b;}
    10     void set_hw(bool b) {hw = b;}
    11     void set_other(bool b) {hw = b;}
    12 private:
    13     bool hw;//硬件错误而非IO错误
    14     bool io;//IO错误
    15     bool other;//其他错误
    16 };
    17 
    18 int main(void){
    19     constexpr Debug io_sub(false, true, false);//调试IO
    20     if(io_sub.any()) cerr << "print appropriate error messages" << endl;
    21 
    22     constexpr Debug prod(false);//无调试
    23     if(prod.any()) cerr << "print an error message" << endl;
    24     return 0;
    25 }

    constexpr 构造函数必须初始化所有数据成员,初始值或者使用 constexpr 构造函数,或者是一条常量表达式。

  • 相关阅读:
    fork-vfork -exit&_exit
    drop_cache-sar
    性能问题eg
    性能工具-mem
    性能工具-io工具
    linux后台开发常用调试工具
    GDB的原理
    可变参数以及stdcall
    linux 中断softirq tasklet
    linux kernel RCU 以及读写锁
  • 原文地址:https://www.cnblogs.com/geloutingyu/p/8207124.html
Copyright © 2011-2022 走看看