zoukankan      html  css  js  c++  java
  • 聚合类和字面值常量类

    聚合类

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

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

    下面的类都是一个聚合类

    struct Data 

    {

      int ival;

      string s;

    };

    我们可以提供一个花括号括起来的成员初始化列表,并用它初始化聚合类的数据成员:

    //val1.ival=0;val1.s=string("Anna")

    Data val1={"Anna",1024"};

    初始值的顺序必须与声明的顺序一致,也就是说,第一个成员的初始值要放在第一个,然后是第二个,以此类。下面的例子是错误的:

    //错误:不是使用"Anna"初始化ival,也不能使用1024初始化s

    Data val2={"Anna",1024};

    与初始化数组元素的规则一样,如果初始值列表中的元素个数少于类的成员数量,则靠后的成员被值初始化。初始值列表的元素个数绝对不能超过类的成员数量。

    值得注意的是,显示地初始化类的对象的成员存在三个明显的缺点:

    • 要求类的所有成员都是public的
    • 将正确初始化每个对象的每个成员的重任交给了类的用户(而非类的作者)。因为用户很容易忘掉某个初始值,或者提供一个不恰当的初始值,所以这样的初始化过程冗长乏味而且容易出错。
    • 添加或删除一个成员之后,所有的初始化语句都需要更新。

    字面值常量类

    我们提到过constexpr函数的参数和返回值必须是字面值类型,除了算术类型、引用和指针外,某些类也是字面值类型。和其他类不同,字面值类型的类可能含有constexpr函数成员。这样的成员必须符合constexpr函数的所有要求,它们是隐式const的。

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

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

    constexpr构造函数

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

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

    class Debug{
    public:
        constexpr Debug(bool b=true):hw(b),io(b),other(b) {}
        constexpr Debug(bool h,bool i,bool o):hw(h),io(i),other(o) {}
        constexpr bool any() {return hw||io||other;}
        void set_io(bool b) {io=b;}
        void set_hw(bool b) {hw=b;}
        void set_other(bool b) {hw=b;}
    private:
        bool hw;
        bool io;
        bool other;
    };

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

    constexpr构造函数用于生成constexpr对象以及constexpr函数的参数或返回类型:

    constexpr Debug io_sub(false,true,false);  //调试IO

    if(io_sub.any())  //等价于if(true)

      cerr<<"print appropriate error messages"<<endl;  

    constexpr Debug prod(false);  //无调试

    if(prod.any())  //等价于if(false)

      cerr<<"print an error message"<<endl;

  • 相关阅读:
    网页调用手机端的方法
    文章分类和标签的数据库设计
    linux 查看进程所在目录
    php-fpm 解析
    php-fpm.conf 解析
    php-fpm 操作命令
    php 获取 post 请求体参数
    获取请求 header 中指定字段的值
    redis 限制接口访问频率
    redis 常用操作
  • 原文地址:https://www.cnblogs.com/wuchanming/p/3901401.html
Copyright © 2011-2022 走看看