智能家居引热议 那些智能家电APP你知道吗?

构造函数再探

构造函数初始值列表

 Sales_data::Sales_data(const string &s, unsigned cnt, double price)
    {
        bookNo=s;
        units_sold=cnt;
        revenue=cnt*price;
    }

这个构造函数和这个效果是一样的
    Sales_data(const std::string &s, unsigned n, double p):
        bookNo(s),units_sold(n),revenue(p*n){}

构造函数的初始值有时必不可少

当成员是const类型或者是引用的时候就必须将其初始化,或者是类类型的时候,且该类没有构造函数定义的时候,那么也要将其初始化
class ConstRef
{
public:
    ConstRef(int ii);
private:
    int i;
    const int ci;
    int &ri;
};

//错误的构造函数的初始化
ConstRef::ConstRef(int ii)
{
    //赋值
    i=ii;       //正确
    ci=ii;      //错误:不能给const赋值
    ri=i;       //错误:ri没被初始化
}
//正确的打开方式
ConstRef::ConstRef(int ii):i(ii),ci(ii),ri(i)
{
    
}

建议:使用构造函数初始值(就是上面的正确打开方式)
在很多类中,初始化和赋值的区别事关底层效率问题,前者(就是上面的正确打开方式)直接初始化,后者(赋值错误打开方式)先初始化后赋值。



成员初始化的顺序

成员初始化的顺序和他们在类定义中的出现顺序一致。
class X
{
    int i;  //先被初始化
    int j;  //后被初始化
public:
    X(int val):j(val),i(j){}
};

<span style="font-weight: normal;">class Sales_data
{
    //为Sales_data的非成员函数所做的友元声明
    friend Sales_data add(const Sales_data&, const Sales_data&);
    friend std::istream &read(std::istream&, Sales_data&);
    friend std::ostream &print(std::ostream&, const Sales_data&);


public:         //增加了访问说明符
    //构造函数
    Sales_data() = default;
    Sales_data(const std::string &s, unsigned n, double p):
        bookNo(s),units_sold(n),revenue(p*n){}
    Sales_data(const std::string s="11"):bookNo(s){cout<<"xxxx"<<endl;}
    Sales_data(std::istream &is){read(is, *this);}
    /*
    Sales_data::Sales_data(const string &s, unsigned cnt, double price)
    {
        bookNo=s;
        units_sold=cnt;
        revenue=cnt*price;
    }*/


    //普通成员函数
    std::string isbn()const {return bookNo;}
    Sales_data &combine(const Sales_data&);
private:
    double avg_price() const
    {
        return units_sold ? revenue/units_sold : 0;
    }
    std::string bookNo;
    unsigned units_sold=0;
    double revenue=0.0;
};

//Sales_data接口的非成员组成部分的声明
Sales_data add(const Sales_data&, const Sales_data&);
std::istream &read(std::istream&, Sales_data&);
std::ostream &print(std::ostream&, const Sales_data&);


int main()
{
    Sales_data next();
    Sales_data last("9-999-99999-9");

    return 0;
}</span>

这里面,main函数里面一个调用的defalut一个调用的是
<span style="font-weight: normal; ">Sales_data(const std::string s="11"):bookNo(s){cout<<"xxxx"<<endl;}</span>


委托构造函数

    //构造函数
    Sales_data(const std::string &s, unsigned n, double p):
        bookNo(s),units_sold(n),revenue(p*n){}

    //其余构造函数都委托给另外构造函数
    Sales_date():Sales_data("",0,0) {}
    Sales_data(std::string s):Sales_data(s,0,0) {}
    Seles_data(std::istream &is):Sales_data() {read(is, *this);}


聚合类

聚合类使得用户可以直接访问其成员,并且具有特殊的初始化语法形式。
一般使用struct定义的类就是聚合类
并且声明一个类的对象的时候,初始值顺序必须和声明顺序一致


字面值常量类

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) {other=b;}
private:
    bool hw;        //硬件错误
    bool io;        //IO错误
    bool other;     //其他错误
};

使用了constexpr的构造函数意味着1、不能有返回值2、拥有唯一可执行的语句返回语句。。。。综合就是函数体应该是空的。
这里我觉得书上这样翻译纯属扯淡,自相矛盾,应该看英文版本的!!!可惜my English is very pool!!


PS:坚持不懈,不在多,而在精华,但是有时候会给一点糟粕,那是因为时间过得太快,不能再那些没必要的小事上浪费时间,但是碰到自己不熟悉的,不清楚的那么你就得好好看看一看,停下脚步认真的学一学了!!!!










智能家居引热议 那些智能家电APP你知道吗?,,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。