类的const成员&&初始化列表

举报
芒果_Mango 发表于 2022/07/31 23:10:07 2022/07/31
【摘要】 大家好,我是芒果,一名非科班的在校大学生。对C/C++、数据结构、Linux及MySql、算法等领域感兴趣,喜欢将所学知识写成博客记录下来。 希望该文章对你有所帮助!如果有错误请大佬们指正!共同学习交流作者简介:CSDN C/C++领域新星创作者https://blog.csdn.net/chuxinchangcun?type=blog掘金LV3用户 https://juejin.cn/us...

大家好,我是芒果,一名非科班的在校大学生。对C/C++、数据结构、Linux及MySql、算法等领域感兴趣,喜欢将所学知识写成博客记录下来。 希望该文章对你有所帮助!如果有错误请大佬们指正!共同学习交流

作者简介:


7.const成员

7.1 const修饰类的成员函数

const修饰的类成员函数称之为const成员函数,const修饰类成员函数,实际修饰该成员函数隐含的this** **指针,表明在该成员函数中不能对类的任何成员进行修改。

image-20220116173037948


image-20220119114622451


总结:成员函数加上const是好的,建议能加const的都加上.这样普通对象和const对象都可以调用该函数了!

但是如果要修改成员变量的成员函数是不能加的,比如日期类中的 += ++ 等

对于日期类函数: += 和 -= ++ – 不可以加const,因为会对原来对象进行改变。+和-可以加const,因为改变的是拷贝构造的临时对象,原来的 对象不变。


8.取地址及const取地址操作符重载

这两个默认成员函数一般不用重新定义 ,编译器默认会生成。

class Date
{
public :
    Date* operator&()
    {
        return this ;
    }
    const Date* operator&()const
    {
        return this ;
    }
private :
    int _year ; // 年
    int _month ; // 月
    int _day ; // 日
};

这两个运算符一般不需要重载,使用编译器生成的默认取地址的重载即可,只有特殊情况,才需要重载,比 如想让别人获取到指定的内容!

& 没有重载也可以使用,他是默认成员函数!我们不写,编译器默认生成一份。如果想自己实现:

image-20220119115528669


1.再谈构造函数

1.1构造函数体赋值

在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值。

class Date
{
public:
    //默认构造函数 -> 赋初始值
    Date(int year, int month, int day)
    {
        _year = year;
        _month = month;
        _day = day;
    }
private:
    int _year;
    int _month;
    int _day;
};

虽然上述构造函数调用之后,对象中已经有了一个初始值,但是不能将其称作为类对象成员的初始化,构造 函数体中的语句只能将其称作为赋初值,而不能称作初始化。因为初始化只能初始化一次,而构造函数体内 可以多次赋值。


1.2 初始化列表

初始化列表:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括 号中的初始值或表达式。

例子:

class Date
{
public:
    //初始化列表
    Date(int year, int month, int day)
        :_year(year)
        ,_month(month)
        , _day(day)   
        , _N(10)
    {}
private:   //声明
    int _year;
    int _month;
    int _day;
    const int _N;
};
int main()
{
    Date d1(2022, 1, 1); //对象定义/对象实例化
    return 0;
}

常量必须在定义的时候初始化,常量只有一次机会初始化

const int j;//err
const int j = 0;//OK

如果没有初始化列表就初始化不了_N

image-20220122105602377

这里报错,说明到构造函数体内的时候,成员变量已经定义出来了

初始化列表:成员变量定义的地方,哪个对象的成员变量? -> 谁调用构造函数就是对象就是谁

image-20220122110054388


image-20220122111601464


image-20220122112022338


【注意】

  1. 每个成员变量在初始化列表中只能出现一次(初始化只能初始化一次)
  2. 类中包含以下成员,必须放在初始化列表位置进行初始化: 引用成员变量 const成员变量 自定义类型成员(该类没有默认构造函数)
class A
{
    public:
    A(int a)
        :_a(a)
        {}
    private:
    int _a;
};
class B
{
    public:
    B(int a, int ref)
        :_aobj(a)
        ,_ref(ref)
        ,_n(10)
    {}
private:
    A _aobj; // 没有默认构造函数
    int& _ref; // 引用
    const int _n; // const
};

3.尽量使用初始化列表初始化,因为不管你是否使用初始化列表,对于自定义类型成员变量,一定会先使 用初始化列表初始化。

class Time
{
public:
    Time(int hour = 0)
        :_hour(hour)
    {
        cout << "Time()" << endl;
    }
private:
    int _hour;
};
class Date
{
public:
    Date(int day)
    {}
private:
    int _day;
    Time _t;
};
int main()
{
    Date d(1);
}

image-20220122112605209


4.成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关

例子:

class A
{
public:
    A(int a)
        :_a1(a)
        , _a2(_a1)
    {}
    void Print() {
        cout << _a1 << " " << _a2 << endl;
    }
private:
    int _a2;
    int _a1;
};
​
int main() 
{
    A aa(1);
    aa.Print();
}

输出:image-20220122112737141

解析

image-20220122113014994

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。