万有斥力 发表于 2022-6-25 02:35:13

类和对象(下)

类和对象(下)



[*]前言
[*]1.再谈构造函数
[*]

[*]1.1 构造函数体赋值
[*]1.2 初始化列表
[*]1.3 explicit关键字

[*]2. static成员
[*]

[*]2.1 概念
[*]2.2 特性

[*]3.C++11 的成员初始化新玩法。
[*]4. 友元
[*]

[*]4.1 友元函数
[*]4.2 友元类

[*]5. 内部类
[*]

[*]5.1概念及特性

[*]6. 练习题
[*]7. 再次理解封装
[*]8. 再次理解面向对象

前言

   https://img-blog.csdnimg.cn/734f0250dcd146b2a1f0736f56f5b9c2.png
哈喽大家好,我是                                                      鹿                               九                               丸                                                 \color{red}{鹿九丸}                  鹿九丸,今天给大家带来的是类和对象(下)。
如果大家在看我的博客的过程中或者学习的过程中以及在学习方向上有什么问题或者想跟我交流的话可以加我的企鹅号:                                             2361038962                                       \color{red}{2361038962}                  2361038962,或者寄邮件到相应的邮箱里:                                                      2361038962                               @                               q                               q                               .                               c                               o                               m                                                 \color{red}{2361038962@qq.com}                  2361038962@qq.com,我会尽量帮大家进行解答!
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 初始化列表

初始化列表:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括号中的初始值或表达式。
//函数体内初始化
Date(int year = 1, int month = 1, int day = 1)
{
        _year = year;
        _month = month;
        _day = day;
}
//初始化列表
Date(int year = 1, int month = 1, int day = 1)
        :_year(year)
        , _month(month)
        , _day(day)
{
    //此时大括号中还能放东西
}
//我们甚至可以这样混着用
Date(int year = 1, int month = 1, int day = 1)
        :_year(year)
        , _month(month)
{
    _day = day;
} 结论:初始化列表可以认为就是对象成员定义的地方。
【注意】

[*] 每个成员变量在初始化列表中只能出现一次(初始化只能初始化一次)(为什么只能初始化一次?因为那是定义的地方!)
[*] 类中包含以下成员,必须放在初始化列表位置进行初始化:(除了下面三种类型,其它类型既可以在初始化列表进行初始化,也可以在函数体内初始化)


[*]引用成员变量
[*]const成员变量
[*]自定义类型成员(该类没有默认构造函数)
int iref = 10;
class A
{
public:
        A(int a)
                :_a(a)
        {}
private:
        int _a;
};
class B
{
public:
        B(int a)
                :_aobj(a)
                , _ref(iref)
                , _n(10)
        {}
private:
        A _aobj; // 没有默认构造函数
        int& _ref; // 引用
        const int _n; // const
}; 问:对于没有默认构造函数的自定义类型的成员,假如不采用初始化列表的方式,我们还有什么办法来对其进行初始化?
答:
B(int a)
{
        A aa(a);//A是自定义类型的类型名
        _aa = aa;//_aa是自定义类型的成员变量名
} 注意:初始化列表中的参数可以有四种来源:


[*] 形参。
A(int a)
    :_a(a)//_a是成员变量
{
   
}
[*] 全局变量。
A()
    :_ref(iref)//ref是成员变量
{
      
}
[*] 常量值。
A()
    :_b(10)//_b是成员变量
{
      
}
[*] C99中声明时的初始化。
class A
{
public:
        A(int a)
        {

        }
private:
        int _a = 10;
};
//此时我们并未显式写出初始化列表,但上面的代码在编译器看来应该是像下面一样的
class A
{
public:
        A(int a)
      :_a(10)
        {

        }
private:
        int _a = 10;
};
注意点1:
下面这种写法是错误的:
class A{public:        A(int a)                :_a(a = 10)        {                cout
页: [1]
查看完整版本: 类和对象(下)