• c++类对象的初始化笔记(1)


    目录

    1. 类成员变量是内置变量或者复合类型

    2. 内置类型,即基本类型

    3. 复合类型

    4. 合成的默认构造函数为内置类型的成员变量初始化的值不确定

    5. =default形式的默认构造函数,也不能初始化为内置类型的成员变量初始化一个确定的值

    6. =default出现在类外部

    7. 解决不确定初始化值的问题

    8. 参考资料


    1. 类成员变量是内置变量或者复合类型

          《C++ primer》第五版中有讲:

    有一条准则,即定义在块中的内置类型或复合类型(数组和指针)默认初始化后,对象的值是不确定的。这条准则同样也适用于默认构造函数,因此,成员变量是内置类型或者复合类型,这个时候,就需要自定义一个默认构造函数,否则,在创建类的对象后就会出现成员变量初始值未被定义的情况。

          这一条准则,很耐人寻味,很多情况下,我们定义的类的成员变量很容易是内置变量或者复合类型。所以我们需要分清楚哪些类型是内置变量,哪些是复合变量。这对于这条准则的运用很重要。

    2. 内置类型,即基本类型

    类型含义最小尺寸(bit)
    bool布尔类型-
    char字符8
    wchar_t宽字符16
    char16_tUnicode字符16
    char32_tUnicode字符32
    short短整型16
    int整型16
    long长整型32
    long long长整型64
    float单精度浮点型6位有效数字
    double双精度浮点型10位有效数字
    long double扩展精度浮点型10位有效数字

    3. 复合类型

    常见的有

    1. 指针

    2. 引用

    为了便于理解,我们还是利用案例来说明情况

    4. 合成的默认构造函数为内置类型的成员变量初始化的值不确定

    1. //sales_data.h
    2. #ifndef SALES_DATA_H
    3. #define SALES_DATA_H
    4. #include
    5. #include
    6. using namespace std;
    7. class SalesData
    8. {
    9. public:
    10. void GetSaleBn()
    11. {
    12. cout << "sales_isbn:" << sale_isbn << endl;
    13. }
    14. private:
    15. int sale_isbn;
    16. };
    17. #endif
    1. //main.cpp
    2. #include "sales_data.h"
    3. #include
    4. int main()
    5. {
    6. std::cout << "SalesData totoal before..." << std::endl;
    7. SalesData total;
    8. total.GetSaleBn();
    9. std::cout << "SalesData totoal after..." << std::endl;
    10. return 0;
    11. }

    编译方法使用以下Makefile:

    1. TGT:= main
    2. SRC:= $(wildcard *.cpp)
    3. OBJ:= $(patsubst %cpp,%o,$(SRC))
    4. CPPFLAGS := -I.
    5. all:$(TGT)
    6. >---@echo "Make successful [0]"
    7. $(TGT):$(OBJ)
    8. >---g++ $^ -o $@
    9. %.o:%.cpp
    10. >---g++ $(CPPFLAGS) $< -c
    11. clear:
    12. >---rm $(OBJ) $(TGT) log.log
    13. .PHONY: all clear

    运行结果如下:

    1. goodstudy@xgoodstudyVPCEG27YC sales_data (study) $ ./main
    2. SalesData totoal before...
    3. sales_isbn:32764(值1)
    4. SalesData totoal after...
    5. xugoodstudyuegoodstudyCEG27YC sales_data (study) $ ./main
    6. SalesData totoal before...
    7. sales_isbn:32766(值2)
    8. SalesData totoal after...
    9. //如果不初始化,对象的内置变量成员值是不确定的,这样的程序是不健壮的,值得我们警惕。

    5. =default形式的默认构造函数,也不能初始化为内置类型的成员变量初始化一个确定的值

    sales_data.h文件内容如下

    1. #ifndef SALES_DATA_H
    2. #define SALES_DATA_H
    3. #include
    4. #include
    5. using namespace std;
    6. class SalesData
    7. {
    8. public:
    9. SalesData() = default;
    10. SalesData(int sale_a):sale_isbn(sale_a)
    11. {
    12. }
    13. void GetSaleBn()
    14. {
    15. cout << "sales_isbn:" << sale_isbn << endl;
    16. }
    17. private:
    18. int sale_isbn;
    19. };
    20. #endif

    编译命令参考以上,编译后,编译生成目标文件 ./main

    1. xuehaiyang@xuehaiyang-VPCEG27YC sales_data (study) $ ./main
    2. SalesData totoal before...
    3. sales_isbn:32767(值1)
    4. SalesData totoal after...
    5. xuehaiyang@xuehaiyang-VPCEG27YC sales_data (study) $ ./main
    6. SalesData totoal before...
    7. sales_isbn:32764(值2)
    8. SalesData totoal after...
    9. xuehaiyang@xuehaiyang-VPCEG27YC sales_data (study) $ ./main
    10. SalesData totoal before...
    11. sales_isbn:32766(值3)
    12. SalesData totoal after...
    13. xuehaiyang@xuehaiyang-VPCEG27YC sales_data (study) $

    运行结果显示,手动构造函数和合成的构造函数效果都一样,都不能初始化一个确定的值。

    《C++ primer》第五版讲到,=default既可以声明在类的内部,也可以作为定义出现在类的外部。如果出现在类的内部,表明默认构造函数是内联的,如果出现在类的外部,则表明此构造函数不是内联的。接下来我们补充一个=default出现在类外部的案例

    6. =default出现在类外部

    1. #ifndef SALES_DATA_H
    2. #define SALES_DATA_H
    3. #include
    4. #include
    5. using namespace std;
    6. class SalesData
    7. {
    8. public:
    9. // SalesData() = default;
    10. SalesData();
    11. SalesData(int sale_a):sale_isbn(sale_a)
    12. {
    13. }
    14. void GetSaleBn()
    15. {
    16. cout << "sales_isbn:" << sale_isbn << endl;
    17. }
    18. private:
    19. int sale_isbn;
    20. };
    21. #endif
    1. //sales_data.cpp
    2. #include"sales_data.h"
    3. SalesData::SalesData() =default;

    编译参考以上,结果如下

    1. xuehaiyang@xuehaiyang-VPCEG27YC sales_data (study) $ ./main
    2. SalesData totoal before...
    3. sales_isbn:32767(值1)
    4. SalesData totoal after...
    5. xuehaiyang@xuehaiyang-VPCEG27YC sales_data (study) $ ./main
    6. SalesData totoal before...
    7. sales_isbn:32764(值2)
    8. SalesData totoal after...
    9. xuehaiyang@xuehaiyang-VPCEG27YC sales_data (study) $ ./main
    10. SalesData totoal before...
    11. sales_isbn:32767(值3)
    12. SalesData totoal after...

    结论文章开头说的一样。

    如果想让上述案例成员变量的值是确定的,可以有多种方法,其中一种就是可以在定义内置成员变量时,就显式的给出确定的值,以下说明了这点。

    7. 解决不确定初始化值的问题

    1. //sales_data.h
    2. #ifndef SALES_DATA_H
    3. #define SALES_DATA_H
    4. #include
    5. #include
    6. using namespace std;
    7. class SalesData
    8. {
    9. public:
    10. SalesData() = default;
    11. SalesData(int sale_a):sale_isbn(sale_a)
    12. {
    13. }
    14. void GetSaleBn()
    15. {
    16. cout << "sales_isbn:" << sale_isbn << endl;
    17. }
    18. private:
    19. int sale_isbn = 0;
    20. };
    21. #endif

    main.cpp参考之前的案例,结果如下

    1. xuehaiyang@xuehaiyang-VPCEG27YC sales_data (study) $ ./main
    2. SalesData totoal before...
    3. sales_isbn:0
    4. SalesData totoal after...

    8. 参考资料

    《C++ primer》第五版

  • 相关阅读:
    Linux Kernel入门到精通系列讲解(QEMU-虚拟化篇) 2.5 Qemu实现RTC设备
    【PyTorch】深度学习实践之线性模型Linear Model
    设计模式—结构型模式之外观模式(门面模式)
    MFC关闭预编译头文件后错误解决
    BioVendor sRAGE蛋白解决方案
    Springboot流浪动物管理系统p2326计算机毕业设计-课程设计-期末作业-毕设程序代做
    java计算机毕业设计社区健康信息管理系统源程序+mysql+系统+lw文档+远程调试
    【机器学习】线性回归【上】朴素最小二乘估计
    windows部署python项目(以Flask为例)到docker,通过脚本一键生成dockerfile并构建镜像启动容器
    作为一名开发者,对你影响最深的书籍是哪一本?
  • 原文地址:https://blog.csdn.net/weixin_42108533/article/details/126202231